对共享可变状态的易失性访问

时间:2014-01-11 20:13:28

标签: c# multithreading language-agnostic volatile memory-barriers

我认为在没有其他线程同步的情况下,对共享可变状态的所有访问必须使用某种形式的低级线程安全性(例如内存屏障)以避免操作重新组织(无论是通过编译器,JIT还是CPU)?

例如,在C#中,我必须在任何地方使用Volatile.Read(ref someVar)和Volatile.Write(ref someVar,someValue)吗?我不使用任何其他类型的同步?

我觉得答案是,我必须这样做。但似乎......过度。


一张纸条,在任何人加入之前: 我不是在谈论线程安全或并发性;只是记忆的一致性我很清楚在编写多线程代码时,内存一致性并不是唯一的问题。

1 个答案:

答案 0 :(得分:1)

首先,如果你声明变量volatile,你可以正常读/写它们并获得内存障碍。

对于实际问题:取决于您如何定义“内存一致性”。根据您的使用情况,您不必同步每次写入/读取,您可以只使用一个来确保一次发布多个内容:

// T1:
foo = 5 // non-volatile
bar = 7 // non-volatile
done = True // volatile write

// T2:
if (done) { // volatile read
     foo and bar guaranteed to be 5, respectively 7 with non-volatile reads
}

但是,你仍然需要每个线程至少有一个内存屏障,否则你的代码会“出错”。但那取决于你如何定义“有缺陷”。

我能想到的一个(也是唯一真正的)示例是没有内存保证的宽松CAS,它允许实现不丢弃更新且不强制排序的性能计数器。该特定想法的来源,请参阅here(build.java之前的最后一段)