为什么volatile会产生未定义的行为

Yve*_*ves 2 c++ volatile undefined-behavior

根据我的理解,volatile- 合格价值意味着无论何时访问它们,我们都必须访问地址并获取最新值.

现在我正在阅读有效的现代C++这本书,我不明白为什么在volatile这里创建一个UB:

volatile int vi(0); // initialize vi to 0
vi = 10; // set vi to 10
std::cout << vi; // read vi's value
++vi; // increment vi to 11
vi--; // decrement vi to 10
Run Code Online (Sandbox Code Playgroud)

在执行此代码期间,如果其他线程正在读取vi的值,则它们可能会看到任何内容(例如,-12,68,4090727-任何内容!).这样的代码会有未定义的行为,因为这些语句会修改vi,所以如果其他线程同时读取vi,那么同时存在的读取器和写入器既不是std :: atomic也不是由互斥锁保护,这就是定义数据竞赛.



在我看来,如果其他主题可能看到0,10或11,我可以理解,但为什么这本书说"他们可能会看到任何东西"?

Tar*_*ama 7

本节讨论的volatile是多线程编程安全的常见误解.如果不同的线程同时读取和写入vi,那么您将进行数据竞争,因为没有适当的同步或原子性保证.数据竞争是C++中未定义的行为,因此"任何东西"确实意味着什么.

如果使用正确的原子操作,那么可以保证所有修改vi都不会被其他线程中断,因此您将没有数据竞争,并且您的程序将是安全的.或者,可以使用互斥锁或类似方法引入同步.

请参阅此站点的参考资料,了解有关为何volatile此类事情不安全的更多详细信息.