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

很可能您的“计数”变量不是任何形式的原子,因此您正在获得不同步的并发修改。因此,以下事件序列是可能的:

  • 线程 1 读取“计数”
  • 线程 2 读取“计数”
  • 线程 1 存储 value+1
  • 线程 2 存储 value+1

因此,“for”循环进行了 2 次迭代,但值只增加了 1。由于线程顺序是“随机的”,因此结果也是如此。

当然,事情可能会变得更糟:

  • 线程 1 读取计数
  • 线程 2 增加计数 100 次
  • 线程 1 存储 value+1

在这种情况下,线程 2 完成的所有这 100 次增加都将被撤消。虽然只有当“++”实际上被分成至少 2 个机器指令时才会发生这种情况,但它可以在操作中间被中断。在单指令情况下,您只处理交错的硬件线程。

于 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 + volatile members not working as expected

于 2012-10-06T11:30:07.147 回答