C# 理解Volatile.Read/Write
我试图理解C#Volatile类 正如我读到的:C# 理解Volatile.Read/Write,c#,volatile,thread-synchronization,C#,Volatile,Thread Synchronization,我试图理解C#Volatile类 正如我读到的: Volatile.Write方法强制写入位置中的值 在通话的时候。此外,任何较早的程序顺序 加载和存储必须在调用Volatile.Write之前进行 Volatile.Read方法强制读取位置中的值 在通话的时候。此外,任何以后的程序顺序都会加载 并且存储必须在调用Volatile.Read之后发生 这是否意味着在以下情况下: internal sealed class ThreadsSharingData { private
方法强制写入位置中的值 在通话的时候。此外,任何较早的程序顺序 加载和存储必须在调用Volatile.Write之前进行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(参考m_标志,1)之前等待命令开始写入m_标志
之前,是否执行代码>
这是如何帮助线程同步的
cpu将在Volatile.Write(ref m_标志,1)之前等待命令;在开始写入m_标志之前
嗯,有点。更好的表述方式是:如果任何其他线程看到m_flag
设置为1,那么它们也会看到m_值设置为5
这是如何帮助线程同步的
我不会说它有助于同步,但它确实有助于实现正确性
如果您没有使用volatile读/写,编译器/运行时/cpu可能会在Thread1
方法中对这两条指令重新排序,并且程序将能够打印0、5或什么都不打印
对于易失性读/写,程序将打印5或根本不打印,但从不打印0。这是预期的行为
这对线程同步有什么帮助
从设置其命令的执行顺序的意义上讲,它无助于线程同步。它允许您确保并发线程以特定顺序观察内存中值的更改,在特定顺序对程序逻辑很重要的情况下
CPU是否在Volatile.Write(参考m_标志,1)之前等待命令开始写入m_标志
之前,是否执行代码>
否,写入m_值的命令已执行。但是,其结果可能在CPU内核外部不可见-特别是,在写入5
的命令执行完毕后,在不同内核上运行的线程可能会从m_value
读取旧值。这是因为新值可能在CPU的缓存中,而不是内存中
如果你写信
m_value = 5;
m_flag = 1;
另一个内核可能会以不同的顺序看到写入:首先它会看到m\u标志变为1
,然后它会看到m\u值变为5
。如果您的另一个线程使用m_标志的值
来判断m_值
的有效性,则逻辑可能会被破坏:例如,Thread2
有时可能会打印零。它仅与内存模型较弱的处理器相关,即获取和释放语义很重要的处理器。除了手臂核心外,几乎没有其他核心。它不能代替正确的同步,在没有同步的情况下编写线程安全代码是一个非常高级的概念。否则就已经很好地涵盖了。