内存屏障生成器
阅读 Joseph Albahari 的线程教程,提到以下内容作为内存屏障的生成器:
- C# 的
lock
语句 (Monitor.Enter
/Monitor.Exit
) Interlocked
类上的所有方法- 使用异步回调线程池 - 其中包括异步委托、APM 回调和任务延续
- 设置和等待信令构造
- 任何依赖于信令的内容,例如启动或等待任务
此外,Hans Passant 和 Brian Gideon 添加了以下内容(假设其中没有一个适合其中之一)前面的类别):
- 启动或唤醒线程上下文
- 切换
Thread.Sleep()
我想知道这个列表是否完整(如果实际上可以制作完整的列表)
编辑
- 易失性(读取意味着获取栅栏,写入意味着释放栅栏)
Reading Joseph Albahari's threading tutorial, the following are mentioned as generators of memory barriers:
- C#'s
lock
statement (Monitor.Enter
/Monitor.Exit
) - All methods on the
Interlocked
class - Asynchronous callbacks that use the thread pool — these include asynchronous delegates, APM callbacks, and Task continuations
- Setting and waiting on a signaling construct
- Anything that relies on signaling, such as starting or waiting on a Task
In addition, Hans Passant and Brian Gideon added the following (assuming none of which already fits into one of the previous categories):
- Starting or waking up a thread
- Context switch
Thread.Sleep()
I was wondering if this list was complete (if a complete list could even be practically made)
EDIT additions suggested:
- Volatile (reading implies an acquire fence, writing implies a release fence)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是我对这个主题的看法,并试图在一个答案中提供一个准完整的列表。如果我遇到其他人,我会不时编辑我的答案。
人们普遍认为会导致隐式屏障的机制:
Monitor
类方法,包括 C# 关键字lock
Interlocked
类方法。Volatile
类方法 (.NET 4.5+)。SpinLock
方法包括Enter
和Exit
。Thread.Join
Thread.VolatileRead
和Thread.VolatileWrite
Thread.MemoryBarrier
易失性
关键词。BeginInvoke
方法等。ManualResetEvent
、AutoResetEvent
、CountdownEvent
、Semaphore
、Barrier
等。Control.Invoke
、Dispatcher.Invoke
、等封送操作SynchronizationContext.Post
等。推测(但不确定)导致隐式障碍的机制:
Thread.Sleep
(由我自己和可能其他人提出,因为代码表现出内存屏障问题可以用此方法修复)Thread.Yield
Thread.SpinWait
Lazy
取决于哪个LazyThreadSafetyMode指定了
其他值得注意的提及:
lock
或Interlocked.CompareExchange
。1 这解释了为什么
BackgroundWorker
可以在CancellationPending
属性的基础字段上没有易失性
的情况下正常工作。Here is my take on the subject and to attempt to provide a quasi-complete list in one answer. If I run across any others I will edit my answer from time to time.
Mechanisms that are generally agreed upon to cause implicit barriers:
Monitor
class methods including the C# keywordlock
Interlocked
class methods.Volatile
class methods (.NET 4.5+).SpinLock
methods includingEnter
andExit
.Thread.Join
Thread.VolatileRead
andThread.VolatileWrite
Thread.MemoryBarrier
volatile
keyword.QueueUserWorkItem
,Task.Factory.StartNew
,Thread.Start
, compiler suppliedBeginInvoke
methods, etc.ManualResetEvent
,AutoResetEvent
,CountdownEvent
,Semaphore
,Barrier
, etc.Control.Invoke
,Dispatcher.Invoke
,SynchronizationContext.Post
, etc.Mechanisms that are speculated (but not known for certain) to cause implicit barriers:
Thread.Sleep
(proposed by myself and possibly others due to the fact that code which exhibits a memory barrier problem can be fixed with this method)Thread.Yield
Thread.SpinWait
Lazy<T>
depending on whichLazyThreadSafetyMode
is specifiedOther notable mentions:
lock
orInterlocked.CompareExchange
.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 for discovering this and bringing it to my attention.11This explains why
BackgroundWorker
works correctly without havingvolatile
on the underlying field for theCancellationPending
property.我似乎记得 Thread.VolatileRead 和 Thread.VolatileWrite 方法的实现实际上会导致完整的栅栏,而不是半栅栏。
这是非常不幸的,因为人们可能会在不知不觉中依赖这种行为;他们可能编写了一个需要完整栅栏的程序,认为他们需要半栅栏,认为他们得到了半栅栏,并且如果这些方法的实现确实提供了半栅栏,将会感到非常惊讶。
我会避免这些方法。当然,我会避免所有涉及低锁代码的事情,除了最琐碎的情况之外,我不够聪明,无法正确编写代码。
I seem to recall that the implementations of the Thread.VolatileRead and Thread.VolatileWrite methods actually cause full fences, not half fences.
This is deeply unfortunate, as people might have come to rely upon this behaviour unknowingly; they might have written a program that requires a full fence, think they need a half fence, think they are getting a half fence, and will be in for a nasty surprise if an implementation of these methods ever does provide a half fence.
I would avoid these methods. Of course, I would avoid everything involving low-lock code, not being smart enough to write it correctly in anything but the most trivial cases.
volatile
关键字也充当内存屏障。请参阅 http://blogs.msdn.com/b/布拉达/archive/2004/05/12/130935.aspxThe
volatile
keyword acts as a memory barrier too. See http://blogs.msdn.com/b/brada/archive/2004/05/12/130935.aspx