JMa*_*sch 11 c# concurrency multithreading volatile
我一直在阅读Joe Duffy关于并发编程的书.我有一个关于无锁线程的学术问题.
第一:我知道无锁线程充满了危险(如果你不相信我,请阅读书中有关内存模型的部分)
不过,我有一个问题:假设我有一个带有int属性的类.
多个线程将非常频繁地读取此属性引用的值
值很少会发生变化,当它发生变化时,它将是一个改变它的线程.
如果它确实发生变化,而另一个使用它的操作正在飞行中,那么任何人都不会失去一个手指(任何人使用它的第一件事就是将它复制到局部变量)
我可以使用锁(或readerwriterlockslim来保持读取并发).我可以标记变量volatile(很多例子都是这样做的)
然而,即使是不稳定也可能会带来性能损失.
如果我在更改时使用VolatileWrite,并使读取的访问正常,该怎么办?像这样的东西:
public class MyClass
{
private int _TheProperty;
internal int TheProperty
{
get { return _TheProperty; }
set { System.Threading.Thread.VolatileWrite(ref _TheProperty, value); }
}
}
Run Code Online (Sandbox Code Playgroud)
我不认为我会在现实生活中尝试这一点,但我对答案感到好奇(更重要的是,作为我是否理解我一直在阅读的记忆模型的检查点).
将变量标记为"volatile"有两个影响.
1)读取和写入具有获取和释放语义,因此对于该存储器位置的读取和写入,其他存储器位置的读取和写入将不会"及时向前和向后移动".(这是一个简化,但你明白我的意思.)
2)抖动生成的代码不会"缓存"逻辑上不变的值.
前一点是否与您的场景相关,我不知道; 你只描述了一个内存位置.是否只有易失性写入而不是易失性读取是很重要的由您决定.
但在我看来,后一点非常重要.如果您对非易失性变量进行自旋锁定:
while(this.prop == 0) {}
Run Code Online (Sandbox Code Playgroud)
抖动是在生成此代码的权利范围内,就像您编写的那样
if (this.prop == 0) { while (true) {} }
Run Code Online (Sandbox Code Playgroud)
不管它是否确实如此,我不知道,但它有权利.如果您想要的是代码实际上重新检查每个循环的属性,将其标记为volatile是正确的方法.