易失性与易失性读/写? [英] Volatile vs VolatileRead/Write?

查看:32
本文介绍了易失性与易失性读/写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到任何的 VolatileRead/write 示例(尝试...)但仍然:

I can't find any example of VolatileRead/write (try...) but still:

什么时候我应该使用 volatile 还是 VolatileRead?

When should I use volatile vs VolatileRead?

AFAIK volatile 的全部目的是创建一半围栏,因此:

AFAIK the whole purpose of volatile is to create half fences so:

  • 对于 READ 操作,在当前操作之后的读/写(在其他线程上)不会在栅栏之前通过.因此 - 我们读取了最新值.
  • For a READ operation, reads/writes (on other threads) which comes AFTER the current operation , won't pass before the fence. hence - we read the latest value.

问题 #1

那我为什么需要volatileRead?似乎 volatile 已经完成了这项工作.

So why do I need the volatileRead? it seems that volatile already do the work.

Plus - 在 C# 中所有写入都是易失性(不像在 Java 中说的那样),无论您是写入 volatile 还是非易失性字段 - 所以我问:为什么需要volatileWrite?

Plus - in C# all writes are volatile (unlike say in Java), regardless of whether you write to a volatile or a non-volatile field - and so I ask: Why do I need the volatileWrite?

问题 #2

这是 VolatileRead 的实现:

[MethodImpl(MethodImplOptions.NoInlining)]
public static int VolatileRead(ref int address)
{
    int num = address;
    MemoryBarrier();
    return num;
}

为什么有一行 int num = address;?他们已经有了地址参数,该参数显然包含该值.

Why the line int num = address; is there? they already have the address argument which is clearly holding the value.

推荐答案

你永远不应该使用 Thread.VolatileRead/Write().这是 .NET 1.1 中的一个设计错误,它使用了完整的内存屏障.这在 .NET 2.0 中得到了纠正,但他们无法再修复这些方法,不得不添加一种新的方法来做到这一点,由 System.Threading.Volatile 类提供.这是 jitter 知道的一个类,它替换 jit time 时的方法为适合特定处理器类型的版本.

You should never use Thread.VolatileRead/Write(). It was a design mistake in .NET 1.1, it uses a full memory barrier. This was corrected in .NET 2.0, but they couldn't fix these methods anymore and had to add a new way to do it, provided by the System.Threading.Volatile class. Which is a class that the jitter is aware of, it replaces the methods at jit time with a version that's suitable for the specific processor type.

可通过参考源获得的 Volatile 类的源代码中的注释讲述了这个故事(已编辑以适合):

The comments in the source code for the Volatile class as available through the Reference Source tells the tale (edited to fit):

// 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.

是的,您很难找到它的用法示例.Reference Source 是一本出色的指南,其中包含数以兆字节精心编写、经过测试且历经战火的 C# 代码,用于处理线程.它使用 VolatileRead/Write 的次数:.

And yes, you'll have trouble finding examples of its usage. The Reference Source is an excellent guide with megabytes of carefully written, tested and battle-scarred C# code that deals with threading. The number of times it uses VolatileRead/Write: zero.

坦率地说,.NET 内存模型与 CLR mm 和 C# mm 提出的相互矛盾的假设一团糟,最近才为 ARM 内核添加了新规则.volatile 关键字的怪异语义对于不同的架构意味着不同的东西,这就是一些证据.尽管对于具有弱内存模型的处理器,您通常可以假设 C# 语言规范所说的内容是准确的.

Frankly, the .NET memory models are a mess with conflicting assumptions made by the CLR mm and C# mm with new rules added for ARM cores just recently. The weirdo semantics of the volatile keyword that means different things for different architectures is some evidence for that. Albeit that for a processor with a weak memory model you can typically assume that what the C# language spec says is accurate.

请注意,Joe Duffy 已经放弃了所有的希望,只是持平out 不鼓励使用它.通常,假设您可以比语言和框架提供的原语做得更好,这是非常不明智的.Volatile 类的备注部分将重点带回家:

Do note that Joe Duffy has given up all hope and just flat out discourages all use of it. It is in general very unwise to assume that you can do better than the primitives provided by the language and framework. The Remarks section of the Volatile class bring the point home:

一般情况下,C#lock 语句、Visual Basic SyncLock 语句和Monitor 类提供了最简单、最不容易出错的同步数据访问方式,Lazy 类提供了编写惰性初始化代码的简单方法不直接使用双重检查锁定.

Under normal circumstances, the C# lock statement, the Visual Basic SyncLock statement, and the Monitor class provide the easiest and least error-prone way of synchronizing access to data, and the Lazy class provides a simple way to write lazy initialization code without directly using double-checked locking.

这篇关于易失性与易失性读/写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆