C 11 中的 Volatile 变量
C 11 标准中多线程机器模型的引入引发了有关 volatile 行为的问题变量,传统上用于防止可能导致并发环境中未定义行为的优化。
在 C 98/03 中,内存模型中缺乏对多线程的识别意味着编译器可以优化无法读取易失性变量,从而导致臭名昭著的无休止 while 循环等待变量更改其值的示例。
但是,C 11 内存模型承认并发访问变量的可能性。这是否意味着 volatile 现已被弃用?
编译器优化和未定义行为
答案在于 C 11 内存模型的细微差别。虽然它识别多线程,但它并不能消除在没有正确同步的情况下访问变量时出现未定义行为的可能性。即使在多线程环境中,对共享变量的非原子访问仍然是未定义的。
volatile int x;
void func() {
x = 0;
while (x = = 0) {}
}
因此,在我们的示例代码中,编译器仍然可以自由地优化 while 循环中 x 的读取,从而导致未定义的行为。易失性仅影响内存访问,而不影响线程行为。
内存屏障和线程完整性
线程完整性需要适当的同步机制,以确保一个线程中的写入对另一个线程的可见性。 C 11 内存模型专门定义了写入何时以及如何对其他线程可见。易失性不满足此要求。
易失性保证编译器无法优化从变量读取的内存,但它不提供有关线程可见性的任何保证。由同步结构(如锁或原子操作)发出的内存屏障对于确保写入在核心之间同步是必要的。
结论
在 C 11 中,易失性仍然相关用于防止可能导致不正确的内存访问的优化。然而,这对于多线程编程来说还不够。仍然需要适当的同步机制来保证并发环境中线程的完整性和定义的行为。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3