为什么我使用Parallel.For得到不同的结果?

时间:2012-10-06 09:30:09

标签: c#-4.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);
}

我每次都得到不同的结果,任何人都可以帮助我并告诉我为什么?

2 个答案:

答案 0 :(得分:2)

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

  • 主题1显示“count”
  • 主题2读取“count”
  • 线程1存储值+ 1
  • 线程2存储值+ 1

因此,“for”循环已完成2次迭代,但该值仅增加1.由于线程排序是“随机”,结果也是如此。

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

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

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

答案 1 :(得分: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