0
using System.Threading.Tasks;

const int _Total = 1000000;
[ThreadStatic]
static long count = 0;

static void Main(string[] args)
{
    Parallel.For(0, _Total, (i) =>
    {
        count++;
    });

    Console.WriteLine(count);
}

毎回違う結果が出ますが、誰か助けてくれて、その理由を教えてもらえますか?

4

2 に答える 2

2

ほとんどの場合、「count」変数はどの形式でもアトミックではないため、同期されていない同時変更を取得しています。したがって、次の一連のイベントが可能です。

  • スレッド1は「カウント」を読み取ります
  • スレッド2は「カウント」を読み取ります
  • スレッド1はvalue+1を格納します
  • スレッド2はvalue+1を格納します

したがって、「for」ループは2回の反復を実行しましたが、値は1だけ増加しました。スレッドの順序は「ランダム」であるため、結果になります。

もちろん、事態はさらに悪化する可能性があります。

  • スレッド1の読み取りカウント
  • スレッド2はカウントを100倍に増やします
  • スレッド1はvalue+1を格納します

その場合、スレッド2によって行われた100回の増加はすべて元に戻されます。これは実際には「++」が実際に少なくとも2つのマシン命令に分割されている場合にのみ発生する可能性があるため、操作の途中で中断される可能性があります。1つの命令の場合、インターリーブされたハードウェアスレッドのみを処理します。

于 2012-10-06T09:36:32.643 に答える
1

これは典型的な競合状態のシナリオです。

したがって、おそらく、ThreadStaticはここでは機能していません。この具体的なサンプルでは、​​System.Threading.Interlockedを使用します。

void Main()
{
    int total = 1000000;
    int count = 0;

    System.Threading.Tasks.Parallel.For(0, _Total, (i) =>
    {
    System.Threading.Interlocked.Increment(ref count);      
    });

    Console.WriteLine(count);
}

同様の質問 C#ThreadStatic+揮発性メンバーが期待どおりに機能しない

于 2012-10-06T11:30:07.147 に答える