如何解决是否可以安全地假设在不加锁的情况下更改线程中的全局bool变量是崩溃安全的?
我知道这是不确定的行为。因此,存在数据争用或崩溃的可能性。可以使用atomicbool来避免这种可能性。我对撞车安全性感兴趣。
AFAIU,当一个线程读取另一线程部分写入或撕裂的值时,可能会发生崩溃。 另一方面,布尔值的大小是由实现定义的,但使其大于data model中指针的大小几乎没有道理。
可以安全地假设bool的存储块是否将被更新?因此,其他线程无法读取torn值,因此从不同线程读取/写入全局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_1
和thread_2
将在10秒后返回。但是对于thread_2
,允许编译器假定a_global_boolean
永远不会返回,因此启用优化后,该线程可能永远不会结束。
https://repl.it/repls/UsefulLowAbstracttype#main.cpp(确保您使用-O3进行编译)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。