内存屏障生成器
阅读Joseph
Albahari的线程教程,以下内容是内存障碍的产生者:
- C#的
lock
声明(Monitor.Enter
/Monitor.Exit
) Interlocked
类上的所有方法- 使用线程池的异步回调-其中包括异步委托,APM回调和任务延续
- 设置并等待信令构造
- 任何依赖信令的内容,例如启动或等待任务
此外,Hans Passant和Brian Gideon
添加了以下内容(假设其中一个都不属于先前的类别之一):
- 启动或唤醒线程
- 上下文切换
Thread.Sleep()
我想知道这份清单是否完整(如果可以实际制作出完整的清单)
建议:
- 易失性(阅读意味着获得范围,写作意味着释放范围)
回答:
这是我对这个问题的看法,并试图在一个答案中提供一个准完整清单。如果遇到其他问题,我将不时编辑我的答案。
普遍认为会引起隐性障碍的机制:
- 所有
Monitor
类方法,包括C#关键字lock
- 所有
Interlocked
类方法。 - 所有
Volatile
类方法(.NET 4.5+)。 - 大多数
SpinLock
方法包括Enter
和Exit
。 Thread.Join
Thread.VolatileRead
和Thread.VolatileWrite
Thread.MemoryBarrier
- 该
volatile
关键字。 - 启动一个线程或导致一个代表到另一个线程上执行包括任何
QueueUserWorkItem
,Task.Factory.StartNew
,Thread.Start
,编译器提供的BeginInvoke
方法等 - 使用信令机制,诸如
ManualResetEvent
,AutoResetEvent
,CountdownEvent
,Semaphore
,Barrier
,等。 - 使用编组操作,如
Control.Invoke
,Dispatcher.Invoke
,SynchronizationContext.Post
,等。
推测(但不确定)导致隐式障碍的机制:
Thread.Sleep
(由我本人提出,也可能是其他人提出的,因为使用这种方法可以解决存在内存障碍问题的代码)Thread.Yield
Thread.SpinWait
Lazy<T>
取决于LazyThreadSafetyMode
指定
其他值得注意的提及:
- C#中事件的默认添加和删除处理程序,因为它们使用
lock
或Interlocked.CompareExchange
。 - x86商店具有发布围栏语义
- 尽管ECMA规范没有强制性规定,但Microsoft对CLI的实现已在写入时释放了篱笆语义。
MarshalByRefObject
似乎抑制了子类中的某些优化,这可能使其看起来好像存在隐式内存屏障。感谢Hans Passant发现此问题并将其引起我的注意。1个
1
这说明了为什么BackgroundWorker
不用属性volatile
的基础字段即可正确工作的原因CancellationPending
。
以上是 内存屏障生成器 的全部内容, 来源链接: utcz.com/qa/410223.html