对 Volatile.Read/Write 的理解

Posted

技术标签:

【中文标题】对 Volatile.Read/Write 的理解【英文标题】:understanding of Volatile.Read/Write 【发布时间】:2014-08-10 00:29:57 【问题描述】:

我正在尝试理解 C# Volatile 类。

如我所见:

Volatile.Write 方法强制写入 location 中的值 到通话点。此外,任何早期的程序顺序 加载和存储必须在调用 Volatile.Write 之前发生。

Volatile.Read 方法强制读取位置中的值 在通话点。此外,任何以后的程序顺序加载 并且存储必须在调用 Volatile.Read 之后发生。

这是否意味着在以下情况下:

internal sealed class ThreadsSharingData     
    private Int32 m_flag = 0;
    private Int32 m_value = 0;
    // This method is executed by one thread
    public void Thread1()         
        // Note: 5 must be written to m_value before 1 is written to m_flag
        m_value = 5;
        Volatile.Write(ref m_flag, 1);        
    

    // This method is executed by another thread
    public void Thread2()         
        // Note: m_value must be read after m_flag is read
        if (Volatile.Read(ref m_flag) == 1)
        Console.WriteLine(m_value);        
        

cpu 会等待Volatile.Write(ref m_flag, 1); 之前的命令,然后再开始写入m_flag

这对线程同步有何帮助?

【问题讨论】:

它仅与内存模型较弱的处理器相关,即获取和释放语义很重要的处理器。除了ARM内核之外,剩下的很少。它不是正确同步的替代品,编写没有同步的线程安全代码是一个非常先进的概念。否则,this question 已经很好地涵盖了。 【参考方案1】:

cpu 将等待 Volatile.Write(ref m_flag, 1); 之前的命令在开始写入 m_flag 之前?

哎呀,有点。更好的表达方式是:可以保证,如果任何其他线程看到 m_flag 设置为 1,他们也会看到 m_value 设置为 5。

这对线程同步有何帮助?

我不会说它有助于同步 - 但它确实有助于实现正确性。

如果您不使用 volatile 读取/写入,编译器/运行时/cpu 可能会重新排序 Thread1 方法中的两条指令,并且程序将能够打印 0、5 或什么都没有。

使用易失性读/写,程序将打印 5 或根本不打印,但从不 0。这是预期的行为。

【讨论】:

【参考方案2】:

这对线程同步有何帮助?

从设置命令执行顺序的意义上说,它无助于线程同步。它使您可以确保并发线程以特定顺序观察内存中值的更改,以防特定顺序对您的程序逻辑很重要。

[是否] CPU 在开始写入m_flag 之前等待Volatile.Write(ref m_flag, 1); 之前的命令?

不,写入m_value 的命令已经执行。但是,它的结果可能在 CPU 内核之外不可见 - 特别是,运行在不同内核上的线程可能会从 m_value 读取旧值 在向其写入 5 的命令之后执行完毕。这是因为新值可能在 CPU 的缓存中,而不是在内存中。

如果你写

m_value = 5;
m_flag = 1;

而不是Volatile.Write(ref m_flag, 1),另一个核心可能会以不同的顺序看到写入:首先它会看到m_flag变成1,然后它会看到m_value变成5。如果你的其他线程使用m_flag的值来判断m_value的有效性,那么逻辑可能会被破坏:例如Thread2可能偶尔会打印零。

【讨论】:

以上是关于对 Volatile.Read/Write 的理解的主要内容,如果未能解决你的问题,请参考以下文章

Flink--对DataSource的理解

谈谈你对广播的理解?

对openResty的理解

谈谈你对面向对象的理解

C#对委托的初步理解理解

对匿名函数的深入理解(彻底版)