4

cntネストされた内に変数( )があります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 に答える