Oha*_*der 24 c# memory-barriers
阅读Joseph Albahari的线程教程,以下内容被提及为内存障碍的生成器:
lock
陈述(Monitor.Enter
/ Monitor.Exit
)Interlocked
班上的所有方法此外,Hans Passant和Brian Gideon 补充了以下内容(假设其中没有一个已经符合以前的类别之一):
Thread.Sleep()
我想知道这个清单是否完整(如果完整清单甚至可以实际制作)
编辑补充建议:
Bri*_*eon 35
以下是我对该主题的看法,并尝试在一个答案中提供准完整列表.如果我遇到任何其他人,我会不时编辑我的答案.
普遍认为会导致隐含障碍的机制:
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
指定的其他值得注意的提及:
lock
或Interlocked.CompareExchange
.MarshalByRefObject
似乎抑制了子类中的某些优化,这可能使它看起来好像存在隐式内存屏障.感谢Hans Passant发现这一点并引起我的注意.11 这解释了为什么BackgroundWorker
没有volatile
在CancellationPending
属性的基础字段上正常工作.
Eri*_*ert 11
我似乎记得Thread.VolatileRead和Thread.VolatileWrite方法的实现实际上导致完全围栏,而不是半围栏.
这是非常不幸的,因为人们可能在不知不觉中开始依赖这种行为; 他们可能已经编写了需要一个完整的栅栏方案,认为他们需要一个半围栏,认为他们得到一个半围栏,并会在一个讨厌的惊喜,如果这些方法的实现永远不会提供半围栏.
我会避免这些方法.当然,我会避免所有涉及低锁代码的内容,除了最琐碎的情况之外,还不够聪明,不能正确地编写它.
归档时间: |
|
查看次数: |
4193 次 |
最近记录: |