在Parallel.For中,可以使用'WaitAll‘同步每个线程吗?
Parallel.For(0, maxIter, i =>
{
// Do stuffs
// Synchronisation : wait for all threads => ???
// Do another stuffs
});
发布于 2014-05-21 20:31:29
Parallel.For
在后台将循环的迭代批处理到一个或多个可以并行执行的Tasks
中。除非您拥有分区的所有权,否则任务(和线程)的数量是(也应该是!)被抽离了。只有在所有任务都完成后(即不需要WaitAll
),控件才会退出Parallel.For
循环。
当然,这个想法是每个循环迭代都是独立的,不需要同步。
如果在紧密循环中需要同步,那么您没有正确地隔离任务,或者这意味着Amdahl's Law正在生效,问题不能通过并行化来加速。
但是,对于聚合类型模式,您可能需要在每个任务完成后进行同步-使用overload和localInit
/ localFinally
来执行此操作,例如:
// allTheStrings is a shared resource which isn't thread safe
var allTheStrings = new List<string>();
Parallel.For( // for (
0, // var i = 0;
numberOfIterations, // i < numberOfIterations;
() => new List<string> (), // localInit - Setup each task. List<string> --> localStrings
(i, parallelLoopState, localStrings) =>
{
// The "tight" loop. If you need to synchronize here, there is no point
// using parallel at all
localStrings.Add(i.ToString());
return localStrings;
},
(localStrings) => // local Finally for each task.
{
// Synchronization needed here is needed - run once per task
lock(allTheStrings)
{
allTheStrings.AddRange(localStrings);
}
});
在上面的示例中,您也可以只将allTheStrings
声明为
var allTheStrings = new ConcurrentBag<string>();
在这种情况下,我们就不需要在localFinally
中使用lock
。
发布于 2014-05-21 21:44:41
你不应该(因为其他用户所说的原因),但是如果你愿意,你可以使用Barrier
。这可以用来导致所有线程在X个参与者遇到障碍之前的某个时间点等待(阻塞),从而导致障碍继续进行和线程解除阻塞。正如其他人所说,这种方法的缺点是死锁
https://stackoverflow.com/questions/23782923
复制相似问题