C#线程安全快速(est)计数器

Joh*_*oDo 129 c# multithreading counter thread-safety

在C#中以最佳性能获取线程安全计数器的方法是什么?

这很简单:

public static long GetNextValue()
{
    long result;
    lock (LOCK)
    {
        result = COUNTER++;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

但是有更快的选择吗?

Aus*_*nen 227

这会更简单:

return Interlocked.Increment(ref COUNTER);
Run Code Online (Sandbox Code Playgroud)

MSDN Interlocked.Increment


Les*_*Les 105

正如其他人所推荐的那样,Interlocked.Increment性能会比lock().只需看看IL和汇编,您将看到它Increment变成"总线锁定"语句,其变量直接递增(x86)或"添加"到(x64).

此"总线锁定"语句锁定总线,以防止在调用CPU执行操作时另一个CPU访问总线.现在,看一下C#lock()语句的IL.在这里,您将看到Monitor要开始或结束部分的调用.

换句话说,.Net lock()语句比.Net做得更多Interlocked.Increment.

所以,如果你想做的只是增加一个变量,Interlock.Increment会更快.查看所有Interlocked方法,查看可用的各种原子操作,并找到适合您需求的方法.使用lock()时,你想要做更复杂的事情一样多相互关联的递增/递减,或者能够连续访问了比整数更复杂的资源.

  • -1表示实现细节。的确,锁定比原子操作慢得多,但这与IL无关。如果不是因为它们的语义,这些函数调用将比原子操作快得多,这不是IL固有的要求。 (2认同)

小智 26

我建议你在System.Threading库中使用.NET的内置互锁增量.

以下代码将通过引用递增long变量,并且完全是线程安全的:

Interlocked.Increment(ref myNum);
Run Code Online (Sandbox Code Playgroud)

来源:http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx