gpt4 book ai didi

c# - Volatile.Read 和 Volatile.Write 背后的逻辑是什么?

转载 作者:太空狗 更新时间:2023-10-30 01:01:06 25 4
gpt4 key购买 nike

来自 MSDN,Volatile.Read():

Reads the value of a field. On systems that require it, inserts a memory barrier that prevents the processor from reordering memory operations as follows: If a read or write appears after this method in the code, the processor cannot move it before this method.

Volatile.Write():

Writes a value to a field. On systems that require it, inserts a memory barrier that prevents the processor from reordering memory operations as follows: If a read or write appears before this method in the code, the processor cannot move it after this method.

我想我能理解Volatile.Read()Volatile.Write()的使用场景,并且看过很多例子解释为什么这两种方法有助于确保程序的正确性。

但我还是想知道,这些规则背后的逻辑是什么?

Volatile.Read()为例,为什么它需要操作after它不能移动before,但不需要任何东西从操作之前它?

还有为什么它与 Volatile.Write() 相反?

谢谢!

最佳答案

围绕 volatile read 和 volatile write 的保证确保如果一个线程使用 volatile write 来指示某事已完成,然后另一个线程使用 volatile read 来通知某事已完成,那么第二个线程将看到那个东西的全部效果。

例如,假设 Thread1初始化对象 A , 而不是对 flag 的 volatile 写入表示完成了。所有涉及初始化对象字段的内存操作 A发生在代码中的标志设置之前。保证这些“在 volatile 写入后无法移动”到flag ,所以当标志在内存中设置时,整个初始化的对象都在内存中,其他线程可以看到它。

现在让我们说 Thread2正在等待那个对象。它有一个不稳定的读取,看到 flag设置,然后读取 A 的字段并根据阅读的内容做出决定。这些读取操作发生在代码中的 volatile 读取之后, volatile 读取保证确保它们将在内存中的 volatile 读取之后发生,因此 Thread2保证看到对象 A 的完全初始化字段,而不是之前存在的任何东西。

所以:作者写道 Thread1在 volatile 写入 flag 之前确实进入内存,这显然必须在 Thread2 之前进入内存可以volatile读取,下面读取Thread2在那之后发生,所以它看到正确初始化的对象。

这就是为什么写入不能延迟到 volatile 写入之后,读取不能在 volatile 读取之前移动。反之亦然?

好吧,让我们说 Thread2 ,在它看到 A 之后初始化,做一些工作并将其写入内存 Thread1用于决定如何初始化 A .这些写入保证不会在内存中发生,直到之后 Thread2看到A完成后,读取 Thread1保证在 flag 之前 对这些位置进行操作在内存中设置,所以 Thread2的写入保证不会干扰初始化工作。

关于c# - Volatile.Read 和 Volatile.Write 背后的逻辑是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41582207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com