No *_*ame 12 c# volatile thread-synchronization
我正在尝试理解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);
}
}
Run Code Online (Sandbox Code Playgroud)
Volatile.Write(ref m_flag, 1);在开始写入之前,cpu会等待命令m_flag吗?
这有助于线程同步?
cpu将在Volatile.Write之前等待命令(ref m_flag,1); 在开始写入m_flag之前?
Eeeh,有点儿.一个更好的方法是:它保证,如果任何其他线程看到m_flag设置为1,它们也会看到m_value设置为5.
这有助于线程同步?
我不会说它有助于同步 - 但它确实有助于实现正确性.
如果您没有使用易失性读/写,则编译器/运行时/ cpu可能会重新排序方法中的两条指令Thread1,并且程序可以打印0,5或根本不打印.
使用易失性读/写,程序将打印5或根本不打印,但从不打印0.这是预期的行为.
这对线程同步有何帮助?
从设置命令执行顺序的意义上来说,它无助于线程同步。它可以让您确保并发线程以特定顺序观察内存中值的更改(在特定顺序对于程序逻辑很重要的情况下)。
Volatile.Write(ref m_flag, 1);[] CPU在开始写入之前是否等待命令m_flag?
不,要写入的命令m_value已经执行。但是,其结果在 CPU 核心之外可能不可见 - 特别是,在不同核心上运行的线程可能会在写入它的命令完成执行m_value 后读取旧值。5这是因为新值可能在CPU的缓存中,而不是在内存中。
如果你写
m_value = 5;
m_flag = 1;
Run Code Online (Sandbox Code Playgroud)
而Volatile.Write(ref m_flag, 1)另一个核心可能会以不同的顺序看到写入:首先它会看到成为m_flag,1然后它会看到m_value成为5。如果您的其他线程使用 的值m_flag来判断 的有效性m_value,则逻辑可能会被破坏:例如,Thread2可能偶尔会打印零。
| 归档时间: |
|
| 查看次数: |
3099 次 |
| 最近记录: |