3

在 Parallel.For 中,是否可以将每个线程与 'WaitAll' 同步?

  Parallel.For(0, maxIter, i =>
  {
            // Do stuffs

           // Synchronisation : wait for all threads => ???

           // Do another stuffs
  });
4

2 回答 2

5

Parallel.For,在后台,将循环的迭代分批成一个或多个Tasks,可以并行执行。除非您拥有分区的所有权,否则任务(和线程)的数量将(并且应该!)被抽象掉。控制只会在Parallel.For所有任务完成后退出循环(即不需要WaitAll)。

这个想法当然是每个循环迭代都是独立的,不需要同步。

如果在紧循环中需要同步,那么说明你没有正确隔离Tasks,或者这意味着Amdahl定律生效,不能通过并行化来加速问题。

但是,对于聚合类型模式,您可能需要在完成每个任务后进行同步 - 使用带有/的重载来执行此操作,例如:localInitlocalFinally

// 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>();

在这种情况下,我们不需要locklocalFinally.

于 2014-05-21T12:31:29.063 回答
0

您不应该(出于其他用户所述的原因),但如果您愿意,您可以使用Barrier. 这可用于使所有线程在 X 数量的参与者遇到障碍之前在某个点等待(阻塞),从而导致障碍继续进行并且线程解除阻塞。正如其他人所说,这种方法的缺点是死锁

于 2014-05-21T13:44:40.657 回答