为什么允许编译器优化这个繁忙的等待循环?
#include <iostream>
#include <thread>
#include <mutex>
int main()
{
std::atomic<bool> ready = false;
std::thread threadB = std::thread([&]() {
while (!ready) {}
printf("Hello from B\n");
});
std::this_thread::sleep_for(std::chrono::seconds(1));
printf("Hello from A\n");
ready = true;
threadB.join();
printf("Hello again from A\n");
}
这是 CppCon 演讲中的一个例子https://www.youtube.com/watch?v=F6Ipn7gCOsY&ab_channel=CppCon(17分钟)
目标是先打印Hello from A然后允许threadB开始。很明显,应该避免忙等待,因为它使用了大量的 CPU。
作者说while (!ready) {}循环可以ready由编译器优化(通过将 的值放入寄存器),因为编译器看到threadB从不睡觉所以ready永远不会改变。但是即使线程从不休眠,另一个线程仍然可以更改该值,对吗?没有数据竞争,因为它ready是原子的。作者声明这个代码是UB。有人可以解释为什么允许编译器进行这样的优化吗?
回答
作者在视频下方的其中一条评论中承认他错了: