Roy*_*mir 29 c# multithreading volatile .net-4.0
我找不到任何 VolatileRead/write(尝试...)的例子,但仍然:
我何时应该使用volatilevs VolatileRead?
AFAIK的全部目的volatile是创造半围栏所以:
问题#1
那我为什么需要volatileRead?似乎volatile已经做好了工作.
另外 - 在C#中,所有写入都是易失性的(与Java中不同),无论您是写入volatile还是非易失性字段 - 所以我问:为什么我需要 volatileWrite?
问题2
这是实施VolatileRead:
[MethodImpl(MethodImplOptions.NoInlining)]
public static int VolatileRead(ref int address)
{
int num = address;
MemoryBarrier();
return num;
}
Run Code Online (Sandbox Code Playgroud)
为什么这条线路int num = address;在那里?他们已经有了明确保持价值的地址参数.
Han*_*ant 36
你永远不应该使用Thread.VolatileRead/Write().这是.NET 1.1中的一个设计错误,它使用了完整的内存屏障.这已在.NET 2.0中得到纠正,但他们无法再修复这些方法,并且必须添加一种新方法来实现它,由System.Threading.Volatile类提供.这是一个抖动所知的类,它在jit时用一个适合特定处理器类型的版本替换方法.
通过参考源提供的Volatile类的源代码中的注释告诉故事(编辑为适合):
// Methods for accessing memory with volatile semantics. These are preferred over
// Thread.VolatileRead and Thread.VolatileWrite, as these are implemented more
// efficiently.
//
// (We cannot change the implementations of Thread.VolatileRead/VolatileWrite
// without breaking code that relies on their overly-strong ordering guarantees.)
//
// The actual implementations of these methods are typically supplied by the VM at
// JIT-time, because C# does not allow us to express a volatile read/write from/to
// a byref arg. See getILIntrinsicImplementationForVolatile() in jitinterface.cpp.
Run Code Online (Sandbox Code Playgroud)
是的,你很难找到它的用法示例.参考源是一个很好的指南,有兆字节的精心编写,测试和战斗伤痕累累的C#代码,处理线程.它使用VolatileRead/Write的次数:零.
坦率地说,.NET内存模型混乱了CLR mm和C#mm所做的相互矛盾的假设,最近刚为ARM内核添加了新的规则.volatile关键字的怪异语义对于不同的体系结构意味着不同的东西,这是一些证据.虽然对于具有弱内存模型的处理器,您通常可以假设C#语言规范所说的准确.
请注意,Joe Duffy放弃了所有的希望,并且不再劝阻所有人使用它.假设您可以比语言和框架提供的原语做得更好,这一般是非常不明智的.Volatile类的备注部分带来了重点:
在正常情况下,C#lock语句,Visual Basic SyncLock语句和Monitor类提供了同步访问数据的最简单且最不容易出错的方式,而Lazy类提供了一种简单的方法来编写延迟初始化代码而无需直接使用双重检查锁定.
当您需要对代码应用围栏的方式进行更精细的控制时,您可以使用static Thread.VolatileRead或Thread.VolatileWrite.
声明变量volatile意味着编译器不会缓存它的值并始终读取字段值,并且在执行写入时,编译器会立即写入指定的值.
Thread.VolatileRead和Thread.VolatileWrite这两个方法使您能够在不将变量声明为volatile的情况下进行更细粒度的控制,因为您可以决定何时执行易失性读取操作以及何时执行易失性写入,而无需读取no你声明变量挥发时立即缓存并写入,所以用差的话来说你有更多的控制权和更多的自由......
VolatileRead()读取最新版本的内存地址,并VolatileWrite()写入该地址,使该地址可供所有线程使用.在变量上同时使用VolatileRead()和VolatileWrite()保持一致与将其标记为易失性具有相同的效果.
看看这篇博文,通过示例解释差异......
为什么行int num = address; 在那儿 ?他们已经有了明确保持价值的地址参数.
这是一个防御性的副本,以避免在我们进入方法时外部的某些东西改变了值,将整数值复制到局部变量以避免从外部意外更改.
由于在Visual Basic中不存在volatile关键字,因此您只能选择使用一致VolatileRead()和VolatileWrite()静态方法来实现c#中 volatile关键字的相同效果.
| 归档时间: |
|
| 查看次数: |
6120 次 |
| 最近记录: |