【发布时间】:2021-10-08 00:25:44
【问题描述】:
假设有一个函数在任何给定时间只能由一个线程执行,其余的只是返回(因为已经在处理特定的状态),实现这一点的最佳方法是什么?
public void RunOnce()
{
if(Interlocked.Exchange(ref m_isRunning, 1) == 1)
return;
// Run code that should only be executed once
// What mechanism do we use here to ensure thread safety?
Volatile.Write(ref m_isRunning, 0);
}
如果 m_isRunning 是一个状态(即表示枚举的整数),同样的机制是否适用?
【问题讨论】:
-
您为什么要尝试使用无锁实现?您是否使用适当的同步原语测量了解决方案的性能问题?
-
编写无锁多线程代码很难测试(而且很脆弱;众所周知,维护程序员偶尔会从工作的无锁实现中删除必要的(但看似无用的)代码)。 C# 的
lock机制是轻量级的。你确定你需要自己动手吗? -
@Flydog57 竞争锁根本不是轻量级的。此外,如果我们一直告诉人们使用“锁”,因为替代方案很困难,那么没有人会学习如何编写高性能的多线程应用程序。
-
@Dennis19901 但是当锁被取出时你会返回,这将是真正的快。再一次,您是否真的测量过它的性能并确保它不适合您的使用?很有可能会没事的。编写一个在所有情况下都能正常运行的无锁版本的几率会大大降低。表现前的正确性。
-
用
Interlocked.Exchange(ref m_isRunning, 0);代替Volatile.Write
标签: c# multithreading concurrency thread-safety lockless