【发布时间】:2010-11-24 17:09:07
【问题描述】:
要为多线程应用程序实现无锁代码,我使用了volatile 变量,
理论上:volatile 关键字只是用来确保所有线程都能看到 volatile 变量的最新值;因此,如果线程A 更新变量值并且线程B 在更新发生后读取该变量,它将看到最近从线程 A 写入的最新值。
正如我在 C# 4.0 in a Nutshell 一书中读到的那样
这是不正确,因为
应用 volatile 不会阻止交换写入后读取。
是否可以通过在每次获取 volatile 变量之前添加 Thread.MemoryBarrier() 来解决此问题,例如:
private volatile bool _foo = false;
private void A()
{
//…
Thread.MemoryBarrier();
if (_foo)
{
//do somthing
}
}
private void B()
{
//…
_foo = true;
//…
}
如果这样可以解决问题;考虑我们有一个 while 循环,该循环在其条件之一处依赖于该值;将Thread.MemoryBarrier() 放在while 循环之前是解决问题的正确方法吗?示例:
private void A()
{
Thread.MemoryBarrier();
while (_someOtherConditions && _foo)
{
// do somthing.
}
}
更准确地说,我希望_foo 变量在任何线程随时要求它时提供其最新值;所以如果在调用变量之前插入Thread.MemoryBarrier() 可以解决问题,那么我可以使用Foo 属性而不是_foo 并在该属性的get 中执行Thread.MemoryBarrier() 就像:
Foo
{
get
{
Thread.MemoryBarrier();
return _foo;
}
set
{
_foo = value;
}
}
【问题讨论】:
-
@Aron;不,它不是重复的;这是另一个问题。
-
@Jalal 您是否尝试使用这种方法 volatile/memorybarrier 来解决问题,或者您是否可以使用任何解决问题的方法?
-
@Aron;我正在尝试使用 volatile/memorybarrier 方法解决这个问题。
-
不要将 volatile 与无锁代码混淆。在任何情况下,Volatile 都不会使您的代码线程安全。
标签: c# memory-management nonblocking volatile memory-barriers