如何锁定阵列聚合并行.for



我正在尝试迭代一个2D数组,然后并行添加到另一个2D数组的部分。为循环。我已经找到了在循环中进行积累的例子在一个单一的变量,但我不知道在这里做什么。GridB正在进行积累,所以它当然需要像其中的项目一样被锁定被添加到不同的线程如果它需要被锁定你怎么去锁定像这样的整个数组呢?

int[,] GridA = new int[D + 2, D + 2];
int[,] GridB = new int[D + 2, D + 2];
Parallel.For(1, D+1 , r =>
{
for (int c = 1; c <= D ; c++)
    if (GridA[r, c] != 0)
    {
        int v = GridA[r, c];
        GridB[r - 1, c - 1] += v;
        GridB[r - 1, c] += v;
        GridB[r - 1, c + 1] += v;
        GridB[r, c - 1] += v;
        GridB[r, c + 1] += v;
        GridB[r + 1, c - 1] += v;
        GridB[r + 1, c] += v;
        GridB[r + 1, c + 1] += v;
    }
});

你可以像这样锁定GridB:

Parallel.For(1, D+1 , r =>
{
  for (int c = 1; c <= D ; c++)
  {
    if (GridA[r, c] != 0)
    {
      int v = GridA[r, c];
      lock(GridB) 
      { 
        GridB[r - 1, c - 1] += v;
        // etc.
      }
    }
  }
});

但是,您正在序列化对GridB的所有访问,这有点违背了使用多线程的目的。

如果您想要做的是为每个元素添加一个固定值,那么System.Threading命名空间中的Interlocked.Add将自动执行添加操作,因此您不需要在整个数组上取出锁。

下面是一个用法示例:

Parallel.For(1, D+1 , r =>
{
    for (int c = 1; c <= D ; c++)
      if (GridA[r, c] != 0)
      {
         int v = GridA[r, c];
          Interlocked.Add(ref GridB[r - 1, c - 1], v);
          // rinse, repeat
      }
}

最新更新