在 C# 中使用线程填充随机数的数组
Posted
技术标签:
【中文标题】在 C# 中使用线程填充随机数的数组【英文标题】:fill an array with random numbers using threads in c# 【发布时间】:2021-03-14 08:09:49 【问题描述】:正如在图块中所说,我正在尝试使用 16 个(在我的情况下)线程填充一个带有随机数的字节数组,现在使用一个线程填充一个包含 500000000 个字节的数组大约需要六秒半的时间线程所以逻辑说使用 16 个线程将至少快 10 倍,但后来我尝试这样做,花了 15 秒来填充它,我所做的是我给每个线程一个段来填充相同的数组
代码如下:
static byte[] nums2 = new byte[500000000];
static Random rnd = new Random(123);
static void fill()
for (int i = 0; i < nums.Length; i++)
nums[i] = (byte)rnd.Next(10);
static void fillPart(object ID)
var part = nums2.Length / Environment.ProcessorCount;
int baseN = (int)ID * part;
for (int i = baseN; i < baseN + part; i++)
nums2[i] = (byte)rnd.Next(10);
Console.WriteLine("Done! " + ID);
static void Main(string[] args)
Stopwatch watch = new Stopwatch();
watch.Start();
fill();
watch.Stop();
Console.WriteLine("it took " + watch.Elapsed);
Console.WriteLine();
watch.Reset();
watch.Start();
Thread[] threads = new Thread[Environment.ProcessorCount];
for (int i = 0; i < Environment.ProcessorCount; i++)
threads[i] = new Thread(fillPart);
threads[i].Start(i);
for(int i = 0; i < Environment.ProcessorCount; i++)
threads[i].Join();
watch.Stop();
Console.WriteLine("it took " + watch.Elapsed);
```
would like to understand why is it took 15 seconds or maybe what I did wrong
【问题讨论】:
在多个线程中使用相同的Random
实例是不安全的。
哦,你说得对!它正在工作,只是在 fillpart 函数中添加了一个新的 Random 对象。我想知道为什么
现在的麻烦是您可能同时创建了一堆 Random 实例。为了使它们不会都喷出相同的数字,您将不得不进一步增加复杂性以确保它们以不同的方式播种。
这能回答你的问题吗? How to create byte array and fill it with random data
不,非常不!关键是使用线程@Sinatr
【参考方案1】:
如果是我,我会:
byte[] nums = new byte[500000000];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(nums);
并完成它。
如果你真的想要线程:
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
var dop = 8;
var batchSize = 500000000 / dop;
var bigBytes = Enumerable.Range(0, dop).AsParallel().SelectMany(t =>
var bytes = new byte[batchSize];
rng.GetBytes(bytes); //This *IS* thread-safe
return bytes;
).ToArray();
但我怀疑SelectMany
和ToArray
整理到一个新数组所花费的时间可能会比单线程方法更昂贵。
【讨论】:
酷,我看不出你是如何工作的,也没有使用线程,但是很棒!【参考方案2】:问题是你声明了static Random rnd = new Random(int.MaxValue);
如果您在fillPart
方法中创建Random
实例,那么程序将在一秒钟内完成,所以不是Thread
的问题是rnd.Next(10)
static void fillPart(object ID)
Random rnd = new Random(123);
var part = nums2.Length / Environment.ProcessorCount;
int baseN = (int)ID * part;
int co = 0;
for (int i = baseN; i < baseN + part; i++)
nums2[i] = (byte)rnd.Next(10);
//Console.WriteLine("Done! " + ID + co);
【讨论】:
请参阅我上面关于播种 Random 的评论,以便生成的数组不会重复。 我认为他的问题不在于唯一编号,而在于线程性能。但你是对的,我受到了你的评论的启发以上是关于在 C# 中使用线程填充随机数的数组的主要内容,如果未能解决你的问题,请参考以下文章