我正在调查For循环中的Parallelism Break。
我希望这段代码:
Parallel.For(0, 10, (i,state) =>
{
Console.WriteLine(i); if (i == 5) state.Break();
}
以大多数 6个数字(0..6)产生。 他不仅没有这样做,而且结果长度不同:
02351486
013542
0135642
非常讨厌。 (那里的地狱是Break(){5之后}这里??)
所以我看了msdn
Break可以用于与循环通信,在当前迭代之后不需要运行其他迭代。 如果从迭代的for循环的第100次迭代中调用Break 并行从0到1000,所有小于100的迭代仍然应该 运行,但不需要从101到1000的迭代。
问题#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'th
次迭代。
他没有指数少于100被停止!! - 所以他会全部展示。
我是对的吗?这就是我在我的例子中获得超过5个元素的原因吗?
问题#3:
(i == 5)
时我真正打破了什么?
P.S。
我的意思是,来吧!当我做Break()
时,我希望循环停止。
正如我在常规For
循环中所做的那样。
答案 0 :(得分:10)
最多产生6个数字(0..6)。
问题是这不会最多产生6个数字。
当您点击索引为5的循环时,会发送“中断”请求。 Break()
会导致循环不再处理任何值>5
,但会处理所有值<5
。
但是,任何已经启动的大于5的值仍将被处理。由于各个索引并行运行,因此它们不再被排序,因此您可以进行各种运行,其中某些值>5
(例如示例中的8)仍在执行。
哪些迭代?整个迭代计数器?还是每个帖子?我很确定这是每个帖子。请批准。
这是传递给Parallel.For的索引。 Break()不会阻止项目被处理,但可以保证最多100个项目得到处理,但100以上的项目可能会被处理,也可能不会被处理。
我是对的吗?这就是我在我的例子中获得超过5个元素的原因吗?
是。如果你使用的是像你所示的分区程序,只要你拨打Break()
,你破坏的项目之外的项目将不再安排。但是,已经安排的项目(整个分区)将被完全处理。在您的示例中,这意味着您可能始终处理所有1000个项目。
我怎样才能真正打破(i == 5)?
你是 - 但是当你并行运行时,事情会发生变化。这里的实际目标是什么?如果您只想处理前6项(0-5),则应通过LINQ查询或类似方法限制之前的项。然后,您可以Parallel.For
或Parallel.ForEach
处理6个项目而无需Break()
,无需担心。
我的意思是,来吧!当我做Break()时,我希望循环停止。正如我在常规For循环中所做的那样。
如果您希望尽快停止播放,则应使用Stop()
代替Break()
。这不会阻止已经运行的项目停止,但不会再安排任何项目(包括枚举中较低索引或更早的项目,而不是当前位置)。
答案 1 :(得分:6)
如果从for循环的第100次迭代调用Break,则从0到1000并行迭代
循环的第100次迭代不一定(实际上可能不是)索引为99的那个。
您的主题可以并且将以不确定的顺序运行。遇到.Break()指令时,不会再启动循环迭代。究竟何时发生这种情况取决于特定运行的线程调度的具体情况。
我强烈建议您阅读
Patterns of Parallel Programming
(来自Microsoft的免费PDF)
了解进入TPL的设计决策和设计权衡。
答案 2 :(得分:4)
哪些迭代?整个迭代计数器?还是按线程?
关闭所有已安排(或尚未安排)的迭代。
请记住,委托可能无序运行,无法保证迭代i == 5
将是第六个执行,除非在极少数情况下这种情况不太可能。
Q2:我是对的吗?
不,调度不是那么简单。而是将所有任务排队,然后处理队列。但是每个线程都使用自己的队列,直到它们从其他线程中窃取时为空。这导致无法预测哪个线程将处理代理。
如果委托是非常简单的,那么它可能都会在原始调用线程上处理(没有其他线程有机会窃取工作)。
问题3:当我(i == 5)时,我真正打破了什么?
如果您想要线性(特定)处理,请不要同时使用。
Break
方法用于支持推测性执行:尝试各种方法,并在任何人完成后立即停止。