我正在研究 For 循环中的并行中断。
我希望这段代码:
Parallel.For(0, 10, (i,state) =>
{
Console.WriteLine(i); if (i == 5) state.Break();
}
最多生成 6 个数字 (0..6)。 不仅他没有这样做,而且结果长度不同:
02351486
013542
0135642
非常烦人。 (Break() {after 5} 到底在哪里??)
于是我看了一下msdn
Break may be used to communicate to the loop that no other iterations after the current iteration need be run. If Break is called from the 100th iteration of a for loop iterating in parallel from 0 to 1000, all iterations less than 100 should still be run, but the iterations from 101 through to 1000 are not necessary.
问题#1:
哪些迭代?整体迭代计数器?还是每个线程?我很确定这是每个线程。请批准。
问题#2:
假设我们正在使用并行 + 范围分区(由于元素之间的 cpu 成本没有变化),因此它在线程之间划分数据。所以如果我们有 4 个核心(并且在它们之间完美划分):
core #1 got 0..250
core #2 got 251..500
core #3 got 501..750
core #4 got 751..1000
因此 core #1
中的线程将在某个时候遇到 value=100
并中断。
这将是他的迭代编号 100
。
但是 core #4
中的线程获得了更多的量子,他现在在 900
上。他远超他的第 100 次
迭代。
他没有索引减去 100 被阻止!! - 所以他会展示给他们看。
我说得对吗?这就是我在示例中获得超过 5 个元素的原因吗?
问题#3:
当 (i == 5)
时,我如何真正崩溃?
附:
我的意思是,来吧!当我执行 Break()
时,我希望循环停止。
与我在常规 For
循环中所做的完全一样。
最佳答案
To yield at most 6 numbers (0..6).
问题是这不会产生最多 6 个数字。
发生的事情是,当您遇到索引为 5 的循环时,您会发送“中断”请求。 Break()
将导致循环不再处理任何值 >5
,但处理所有值 <5
.
但是,任何已经开始的大于 5 的值仍将得到处理。由于各种索引并行运行,它们不再有序,所以你会得到各种运行,其中一些值 >5
(例如您示例中的 8)仍在执行中。
Which iterations ? the overall iteration counter ? or per thread ? I'm pretty sure it is per thread. please approve.
这是传递给 Parallel.For 的索引。 Break() 不会阻止处理项目,但会保证处理最多 100 个项目,但可能会处理也可能不会处理超过 100 个的项目。
Am I right ? is that is the reason why I get more than 5 elements in my example ?
是的。如果你像你展示的那样使用分区器,只要你调用 Break()
,您打破的项目将不再被安排。但是,已安排的项目(即整个分区)将得到完全处理。在您的示例中,这意味着您可能始终处理所有 1000 个项目。
How can I truly break when (i == 5) ?
你是 - 但当你并行运行时,事情就变了。这里的实际目标是什么?如果您只想处理前 6 个项目 (0-5),您应该在通过 LINQ 查询或类似查询循环遍历它们之前限制这些项目。然后您可以处理 Parallel.For
中的 6 个项目或 Parallel.ForEach
没有 Break()
不用担心。
I mean , come on ! when I do Break() , I want things the loop to stop. excactly as I do in regular For loop.
你应该使用 Stop()
而不是 Break()
如果你想让事情尽快停止。这不会阻止项目停止已经运行,但不会再安排任何项目(包括索引较低或枚举中比您当前位置更早的项目)。
关于c# - Parallel.For 和 Break() 的误解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12784530/