Mus*_*ici 2 .net c# multithreading
如何同时为变量添加值?如果可以的话会是什么结果?崩溃还是其他什么?
例如:
int a;
Run Code Online (Sandbox Code Playgroud)
所以将有 2 个线程来增加一次价值。
谢谢
当 2 个线程在没有任何同步的情况下添加到共享值时的行为是未定义的。写入不会导致任何类型的崩溃。它只会将该值作为其中一个线程所见的最终值
为了获得定义的行为,您需要添加某种同步,例如锁。
internal static class Holder {
static object m_lock = new object();
static int a;
internal static void Add(int value) {
lock (m_lock) {
a += value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您以不受控制的方式执行此操作,很可能会丢失数据。
每个线程将采取三个步骤:
如果他们都大致一起执行第一步,结果将是增量 1 而不是 2。
此外,存在内存模型问题,其中一个线程可能无法“看到”另一个线程的写入。记忆模型是复杂的野兽...
使用Interlocked.Increment执行原子递增,其中还使用易失性存储器访问,以确保它总是能看到什么其他的线程都写。
损坏的代码示例:
using System;
using System.Threading;
class Test
{
const int Iterations = 1000000;
static int counter;
static void Main()
{
Thread t1 = new Thread(AddLots);
t1.Start();
AddLots();
t1.Join();
Console.WriteLine(counter);
}
static void AddLots()
{
for (int i = 0; i < Iterations; i++)
{
// Broken!
counter++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
刚刚在我的笔记本电脑上运行,显示结果为 1011788。
改变这一行:
counter++;
Run Code Online (Sandbox Code Playgroud)
对此:
Interlocked.Increment(ref counter);
Run Code Online (Sandbox Code Playgroud)
这一切都很好。