3

我正在尝试遍历 2D 数组,然后在 Parallel.For 循环中添加到另一个 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;
    }
});
4

1 回答 1

1

你可以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这违背了使用多个线程的目的。

如果您只想为每个元素添加一个固定值,Interlocked.Add则在System.Threading命名空间中将自动添加,因此您无需对整个数组进行锁定。

以下是使用示例:

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
      }
}
于 2013-06-03T01:19:02.913 回答