假设在没有锁的线程中更改全局bool变量是安全的吗



我知道这是未定义的行为。因此存在数据竞争或崩溃的可能性。可以使用atomicpool来避免这种可能性。我想了解的关于碰撞安全的情况。

AFAIU,当一个线程读取另一个线程部分写入或撕裂的值时,可能会发生崩溃。另一方面,bool的大小是由实现定义的,但在数据模型中让它大于指针的大小是没有意义的。

假设bool的内存块将被更新或不被更新是否安全?因此,其他线程无法读取撕裂的值,因此从不同线程读取/写入全局bool是安全的吗?

不,它不安全。未定义的行为是未定义的。没有规则说它不会崩溃,除非你能想出一种方法让它崩溃。我能想出办法让它崩溃。

例如,假设您有一个函数,它创建了一个线程,该线程在不同步的情况下从该函数写入的同一bool中读取。由于这是UB,编译器可以自由地假设函数永远不会被调用。它甚至不需要为它生成任何代码。如果该函数由if调用,编译器可以假设if的另一个分支将始终被调用。

你甚至没有想过说";任何编译器都不会那么聪明";。很多人曾经说过这样的话,但当编译器变得更聪明时,他们就火烧眉毛了。在过去的一二十年里,我看到了几十起";那个新编译器破坏了我的代码";当然,当代码一直被破坏的时候。

已经有编译器将类似if (x > 2) y = 3; else y = 4;的代码更改为类似y = 3; if (x <= 2) y = 4;的代码。在某些情况下,这甚至可以是一种优化。

不要故意破坏代码。

你不太可能触发崩溃,但你可能会触发其他意想不到的结果:

bool a_global_boolean = false;
void thread_1() {
sleep(10);
a_global_boolean = true;
}
void thread_2() {
while (a_global_boolean == false) {
}
}

您可能预计thread_1thread_2将在10秒后返回。但对于thread_2,编译器可以假设a_global_boolean永远不会返回,因此当启用优化时,该线程可能永远不会结束。

https://repl.it/repls/UsefulLowAbstracttype#main.cpp(确保使用-O3编译(

最新更新