提问人:user22155685 提问时间:11/16/2023 最后编辑:Theodor Zouliasuser22155685 更新时间:11/16/2023 访问量:41
易失性和互锁之间的不一致
Inconsistency between Volatile and Interlocked
问:
以下是源代码:
public static class Volatile
{
// ...
public static ulong Read(ref ulong location);
public static long Read(ref long location);
public static double Read(ref double location);
}
public static class Interlocked
{
// ... Interlocked has only two Read methods as below:
public static ulong Read(ref ulong location);
public static long Read(ref long location);
}
我这里有一些问题,为什么没有对应的“读取double”方法?Interlocked
“Read long”和“Read long”有什么区别。Volatile
Interlocked
答:
2赞
shingo
11/16/2023
#1
Volatile 和 Interlocked 具有不同的功能,因此不应使用“不一致”或“对应”之类的词。
互锁。
在 32 位程序中读取 64 位数字不是原子的,例如
线程 1 | 线程 2 |
---|---|
a = 0x100000002L; |
long b = a; |
在 32 位程序中,您有一定的概率读取仅更新一半的结果,即 或。 确保您只能读取 或 。0x100000000L
2
Interlocked.Read
0
0x100000002L
如果您仍在开发 32 位程序并且需要一种方法,则可以改用:Interlocked.Read(double)
CompareExchange
double d = Interlocked.CompareExchange(ref doubleValue, 0, 0);
挥发性的
对于读写数据的语句,编译器或处理器可以优化执行顺序以提高内存访问效率,例如
线程 1 | 线程 2 |
---|---|
x1 = 1; |
y2 = y1; |
y1 = 2; |
x2 = x1; |
如果不使用 ,你有机会看到 和 ,这是因为之前可能已经执行过了。因此,您需要使用来防止执行顺序被更改。Volatile
y2 == 2
x2 == 0
y1 = 2
x1 = 1
Volatile
线程 1 | 线程 2 |
---|---|
Volatile.Write(ref x1, 1); |
y2 = Volatile.Read(ref y1); |
y1 = 2; |
x2 = x1; |
评论