Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解Volatile.Read/Write_C#_Volatile_Thread Synchronization - Fatal编程技术网

C# 理解Volatile.Read/Write

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

我试图理解C#Volatile类

正如我读到的:

  • 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
有时可能会打印零。

它仅与内存模型较弱的处理器相关,即获取和释放语义很重要的处理器。除了手臂核心外,几乎没有其他核心。它不能代替正确的同步,在没有同步的情况下编写线程安全代码是一个非常高级的概念。否则就已经很好地涵盖了。