Reading Joseph Albahari 的线程教程 http://www.albahari.com/threading/part4.aspx,以下被提及为内存屏障的生成器:
- C#'s
lock
陈述 (Monitor.Enter
/Monitor.Exit
)
- 上的所有方法
Interlocked
class
- 使用线程池的异步回调 - 其中包括异步委托、APM 回调和任务延续
- 设置并等待信令构造
- 任何依赖于信号的事情,例如启动或等待任务
此外,汉斯·帕桑特和布莱恩·吉迪恩添加了以下内容 https://stackoverflow.com/questions/6574389/thread-safe-usage-of-lock-helpers-concerning-memory-barriers(假设没有一个已经属于前面的类别之一):
- 启动或唤醒线程
- 上下文切换
Thread.Sleep()
我想知道这个列表是否完整(是否可以实际制作一个完整的列表)
EDIT建议补充:
这是我对这个主题的看法,并试图在一个答案中提供一个准完整的列表。如果我遇到其他人,我会不时编辑我的答案。
人们普遍认为会造成隐性障碍的机制:
- All
Monitor
包含 C# 关键字的类方法lock
- All
Interlocked
类方法。
- All
Volatile
类方法(.NET 4.5+)。
- Most
SpinLock
方法包括Enter
and Exit
.
Thread.Join
-
Thread.VolatileRead
and Thread.VolatileWrite
Thread.MemoryBarrier
- The
volatile
关键词。
- 任何启动线程或导致委托在另一个线程上执行的操作,包括
QueueUserWorkItem
, Task.Factory.StartNew
, Thread.Start
,编译器提供BeginInvoke
方法等
- 使用信号机制,例如
ManualResetEvent
, AutoResetEvent
, CountdownEvent
, Semaphore
, Barrier
, etc.
- 使用编组操作,例如
Control.Invoke
, Dispatcher.Invoke
, SynchronizationContext.Post
, etc.
推测(但不确定)导致隐性障碍的机制:
-
Thread.Sleep
(由我自己和可能其他人提出,因为可以使用此方法修复表现出内存屏障问题的代码)
Thread.Yield
Thread.SpinWait
-
Lazy<T>
取决于哪个LazyThreadSafetyMode
已指定
其他值得注意的提及:
- C# 中事件的默认添加和删除处理程序,因为它们使用
lock
or Interlocked.CompareExchange
.
- x86 存储具有释放栅栏语义
- 尽管 ECMA 规范并未强制执行,但 Microsoft 的 CLI 实现已释放写入栅栏语义。
-
MarshalByRefObject
seems to suppress certain optimizations in subclasses which may make it appear as if an implicit memory barrier were present. Thanks to Hans Passant https://stackoverflow.com/a/10308000/158779 for discovering this and bringing it to my attention.1
1This explains why BackgroundWorker
works correctly without having volatile
on the underlying field for the CancellationPending
property.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)