【发布时间】:2016-11-21 18:39:57
【问题描述】:
我尝试创建一个多线程骰子滚动模拟 - 只是为了好奇,多线程编程的乐趣以及向其他人展示“随机结果”的效果(很多人无法理解,如果你在其中掷六次拉普拉斯骰子一行,你已经有 1、2、3、4、5 下一个滚动不是 6。)。为了向他们展示 m 骰子的 n 个掷骰的分布情况,我创建了这段代码。
好吧,结果很好,但即使我为每个程序运行单线程的骰子创建了一个新任务。 多线程可以合理地模拟“数百万”次使用 6 个或更多骰子的重掷,因为完成时间会迅速增长。
我从 msdn 中阅读了几个示例,这些示例都表明应该同时运行多个任务。 有人可以给我一个提示,为什么这段代码不使用很多线程/内核? (甚至没有,当我尝试一次运行 400 个骰子并重掷 1000 万次时)
首先我初始化存储结果的锯齿状数组。第一个维度:每个骰子 1 个条目,第二个维度将是每个骰子滚动的眼睛的分布。
接下来我创建一个任务数组,每个任务返回一个结果数组(第二维,如上所述) 这些数组中的每一个都有 6 个条目,代表拉普拉斯 W6 骰子的每一面。如果掷骰结果为 1 只眼睛,则第一个条目 [0] 增加 +1。因此,您可以可视化每个值的滚动频率。
然后我使用一个普通的 for 循环来启动所有线程。在所有线程启动之前,没有迹象表明要等待线程。
最后,我等待所有人完成并总结结果。换了也没关系
Task.WaitAll(任务);到 Task.WhenAll(任务);
我的问题是:为什么该代码不使用我的 CPU 的多个内核?我需要改变什么?
提前致谢!
代码如下:
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
int tries = 1000000;
int numberofdice = 20 ;
int numberofsides = 6; // W6 = 6
var rnd = new Random();
int[][] StoreResult = new int[numberofdice][];
for (int i = 0; i < numberofdice; i++)
{
StoreResult[i] = new int[numberofsides];
}
Task<int[]>[] tasks = new Task<int[]>[numberofdice];
for (int ctr = 0; ctr < numberofdice; ctr++)
{
tasks[ctr] = Task.Run(() =>
{
int newValue = 0;
int[] StoreTemp = new int[numberofsides]; // Array that represents how often each value appeared
for (int i = 1; i <= tries; i++) // how often to roll the dice
{
newValue = rnd.Next(1, numberofsides + 1); // Roll the dice; UpperLimit for random int EXCLUDED from range
StoreTemp[newValue-1] = StoreTemp[newValue-1] + 1; //increases value corresponding to eyes on dice by +1
}
return StoreTemp;
});
StoreResult[ctr] = tasks[ctr].Result; // Summing up the individual results for each dice in an array
}
Task.WaitAll(tasks);
// do something to visualize the results - not important for the question
}
}
【问题讨论】:
-
当您调用
Result时,您会一直阻塞直到Task完成。 -
尽量将您的解释性文本保持在理解和重现问题所需的最低限度。您的问题可能在这一行:
StoreResult[ctr] = tasks[ctr].Result;因为对于Task.Result:“访问属性的 get 访问器会阻塞调用线程,直到异步操作完成;它相当于调用 Wait 方法”。解决方法是删除该行,然后在Task.WaitAll()之后迭代结果。 -
@Quantic:我不知道,我会试试你的建议... ------ BINGO!这解决了问题!
标签: c# multithreading parallel-processing task