4

cnt在 nested 中有一个变量 () parallel.foreach。我运行这个程序,显然它运行良好。有人知道这段代码真的是线程安全的吗?parallel是否可以在循环内定义变量?

谢谢你。

    object obj = new object();
    int total=0;

    Parallel.For(0, 2, i =>
    {
        Parallel.For(0, 1000000, j =>
        {
            int cnt = 0;
            if ((arr[i, j] % 2) == 0)
            {
                Interlocked.Increment(ref cnt);
            }
            lock (obj)
            {
                total= total+ (cnt / 2);
            }
        });
    });
4

2 回答 2

6

此代码是线程安全的 - 唯一的共享数据 ( total) 已正确同步。即使不使用它也是线程安全的Interlocked.Increment(即:在您编辑之前)。

但是,它效率不高。

将重载与本地初始化程序和最后的委托一起使用会好得多。

int total=0;
Parallel.For(0, 2, 
{
    Parallel.For(0, 1000000, 
      local => 0,
      (j, state, local) =>
      {
        if ((arr[i, j] % 2) == 0)
        {
           ++local;
        }
        return local;
      },
      local => Interlocked.Increment(ref total, local)
    );
});
于 2013-03-13T22:17:28.130 回答
0

该代码确实是安全的,因为该lock语句充当完整的围栏操作。它确保增量操作是原子的并且不会受到来自其他线程的竞争

于 2013-03-13T22:18:19.403 回答