C# Thread无一例外地耗尽内存(1000 Monkeys and Typewriters-like program)
C# Thread runs out of memory with no exception (1000 Monkeys and Typewriters-like program)
编辑:使用静态随机解决class。原来 Randoms 不是线程安全的。
public static class StaticRandom
{
static int seed = Environment.TickCount;
static readonly ThreadLocal<Random> random =
new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
public static int Next(int min, int max)
{
return random.Value.Next(min, max);
}
}
这里的程序相对较短,只是为了好玩而写的。该程序在主线程上运行良好,但是当我对其进行多线程处理时,线程似乎无缘无故停止,并且经过研究,它们似乎 运行 堆栈内存不足。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
namespace MonkeysTypewriters
{
class Program
{
private static Thread[] monkeys = new Thread[Environment.ProcessorCount];
private static Random r = new Random();
static void Main(string[] args)
{
string[] dictionary = ReadDictionary();
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < monkeys.Length; i++)
{
monkeys[i] = new Thread(() => GetRandomWord(dictionary));
}
foreach (Thread monkey in monkeys)
{
monkey.Start();
}
foreach (Thread monkey in monkeys)
{
monkey.Join();
}
Console.WriteLine("");
}
Console.WriteLine("Finished");
Console.ReadLine();
}
private static string[] ReadDictionary()
{
return File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/WORDS.TXT");
}
private static string GenerateWord()
{
string word = "";
char nextLetter = (char)r.Next(65, 91);
while (nextLetter != '[')
{
word += nextLetter;
nextLetter = (char)r.Next(65, 92);
}
return word;
}
private static bool ValidateWord(string word, string[] dictionary)
{
return Array.BinarySearch(dictionary, word) >= 0;
}
private static void GetRandomWord(string[] dictionary)
{
string word = "";
while (!ValidateWord(word, dictionary))
{
word = GenerateWord();
}
Console.WriteLine(word);
}
}
}
似乎 运行 GenerateWord 内存不足。谁能指出我正确的方向或告诉我为什么他们 运行 内存不足?
WORDS.TXT 是一个包含大量英文单词的文本文件。
Random
class 不是线程安全的。每次调用 Next
时,它可能会中断 return 相同的数字,这很可能是您遇到的情况,因此 GenerateWord
永远不会 return 是一个有效的词。请参阅 Random 文档,尤其是有关线程安全的部分。
解决此问题的最佳方法是为每个线程提供它自己的 Random
实例。实现此目的的一种简单方法是将 static Random
变成 static ThreadLocal<Random>
:
private static ThreadLocal<Random> r = new ThreadLocal<Random>(
() => new Random()
);
编辑:使用静态随机解决class。原来 Randoms 不是线程安全的。
public static class StaticRandom
{
static int seed = Environment.TickCount;
static readonly ThreadLocal<Random> random =
new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
public static int Next(int min, int max)
{
return random.Value.Next(min, max);
}
}
这里的程序相对较短,只是为了好玩而写的。该程序在主线程上运行良好,但是当我对其进行多线程处理时,线程似乎无缘无故停止,并且经过研究,它们似乎 运行 堆栈内存不足。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
namespace MonkeysTypewriters
{
class Program
{
private static Thread[] monkeys = new Thread[Environment.ProcessorCount];
private static Random r = new Random();
static void Main(string[] args)
{
string[] dictionary = ReadDictionary();
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < monkeys.Length; i++)
{
monkeys[i] = new Thread(() => GetRandomWord(dictionary));
}
foreach (Thread monkey in monkeys)
{
monkey.Start();
}
foreach (Thread monkey in monkeys)
{
monkey.Join();
}
Console.WriteLine("");
}
Console.WriteLine("Finished");
Console.ReadLine();
}
private static string[] ReadDictionary()
{
return File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/WORDS.TXT");
}
private static string GenerateWord()
{
string word = "";
char nextLetter = (char)r.Next(65, 91);
while (nextLetter != '[')
{
word += nextLetter;
nextLetter = (char)r.Next(65, 92);
}
return word;
}
private static bool ValidateWord(string word, string[] dictionary)
{
return Array.BinarySearch(dictionary, word) >= 0;
}
private static void GetRandomWord(string[] dictionary)
{
string word = "";
while (!ValidateWord(word, dictionary))
{
word = GenerateWord();
}
Console.WriteLine(word);
}
}
}
似乎 运行 GenerateWord 内存不足。谁能指出我正确的方向或告诉我为什么他们 运行 内存不足?
WORDS.TXT 是一个包含大量英文单词的文本文件。
Random
class 不是线程安全的。每次调用 Next
时,它可能会中断 return 相同的数字,这很可能是您遇到的情况,因此 GenerateWord
永远不会 return 是一个有效的词。请参阅 Random 文档,尤其是有关线程安全的部分。
解决此问题的最佳方法是为每个线程提供它自己的 Random
实例。实现此目的的一种简单方法是将 static Random
变成 static ThreadLocal<Random>
:
private static ThreadLocal<Random> r = new ThreadLocal<Random>(
() => new Random()
);