C# 4.0 为什么我要用Parallel.来得到不同的结果?

C# 4.0 为什么我要用Parallel.来得到不同的结果?,c#-4.0,C# 4.0,每次我都会得到不同的结果,有人能帮我一下并告诉我原因吗?很可能您的“count”变量不是任何形式的原子变量,因此您得到的是不同步的并发修改。因此,以下事件序列是可能的: 线程1读取“计数” 线程2读取“计数” 线程1存储值+1 线程2存储值+1 因此,“for”循环进行了2次迭代,但该值仅增加了1。由于线程顺序是“随机”的,因此结果也是随机的 当然,情况可能变得更糟: 线程1读取计数 线程2将计数增加100倍 线程1存储值+1 在这种情况下,线程2完成的所有100次增加都将撤消。虽然只有

每次我都会得到不同的结果,有人能帮我一下并告诉我原因吗?

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

  • 线程1读取“计数”
  • 线程2读取“计数”
  • 线程1存储值+1
  • 线程2存储值+1
因此,“for”循环进行了2次迭代,但该值仅增加了1。由于线程顺序是“随机”的,因此结果也是随机的

当然,情况可能变得更糟:

  • 线程1读取计数
  • 线程2将计数增加100倍
  • 线程1存储值+1
在这种情况下,线程2完成的所有100次增加都将撤消。虽然只有当“++”实际上被分割成至少2个机器指令时,它才能真正发生,所以它可以在操作的中间中断。在单指令情况下,您只处理交错的硬件线程。

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

  • 线程1读取“计数”
  • 线程2读取“计数”
  • 线程1存储值+1
  • 线程2存储值+1
因此,“for”循环进行了2次迭代,但该值仅增加了1。由于线程顺序是“随机”的,因此结果也是随机的

当然,情况可能变得更糟:

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

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

这是一个典型的竞争条件场景

因此,ThreadStatic很可能不在这里工作。在此混凝土样本中,使用System.Threading.Interlocated:

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);
}
类似问题
这是一个典型的比赛条件场景

因此,ThreadStatic很可能不在这里工作。在此混凝土样本中,使用System.Threading.Interlocated:

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);
}
类似问题

谢谢你的回答!它很有用!我知道我的“计数”不是原子的,所以我使用[ThreadStatic]属性。MSDN说“表示静态字段的值对于每个线程都是唯一的。”Parallel.for()可以由这么多线程使用,但在每个线程中静态字段可以是唯一的。因此[ThreadStatic]是不对的。我必须删除[ThreadStatic],然后添加“锁”或者一些同步的东西。我是对的吗?嗯,是的。我没有真正意识到“ThreadStatic”是什么意思,甚至可能认为这是一个评论。无论哪种方式,如果您使这个“线程静态”,结果都是相似的,尽管原因不同:每个线程都有自己的“计数”,因此最后您只能从一个线程获得计数。是的,“锁”听起来更好,像“原子的”或“同步的”之类的词或任何语言使用的词也一样。在您的简单循环中,您将看不到并行的任何改进,因为您的循环体根本无法并行运行。你实际上只是在增加开销:-)是的,你是对的。在这个简单的循环中,我没有通过并行来改进,只是增加了开销。谢谢你的帮助。这段代码是真正的并行:并行。对于(1100,(i)=>{arr[i]=i;}。谢谢你的回答!它很有用!我知道我的“计数”不是原子的,所以我使用[ThreadStatic]属性。MSDN说“表示静态字段的值对于每个线程都是唯一的。”Parallel.for()可以由这么多线程使用,但在每个线程中静态字段可以是唯一的。因此[ThreadStatic]是不对的。我必须删除[ThreadStatic],然后添加“锁”或者一些同步的东西。我是对的吗?嗯,是的。我没有真正意识到“ThreadStatic”是什么意思,甚至可能认为这是一个评论。无论哪种方式,如果您使这个“线程静态”,结果都是相似的,尽管原因不同:每个线程都有自己的“计数”,因此最后您只能从一个线程获得计数。是的,“锁”听起来更好,像“原子的”或“同步的”之类的词或任何语言使用的词也一样。在您的简单循环中,您将看不到并行的任何改进,因为您的循环体根本无法并行运行。你实际上只是在增加开销:-)是的,你是对的。在这个简单的循环中,我没有通过并行来改进,只是增加了开销。谢谢你的帮助。这段代码是真正的并行:并行。for(1100,(i)=>{arr[i]=i;})。