C++ 线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取..会遇到问题吗?

mcz*_*nek 2 c++ concurrency

如果一个线程读取另一个线程正在写入的非原子原始变量,是否保证在写入之前或之后读取该值,或者它是否可以在写入期间以某种方式读取某些损坏的版本?

我意识到诸如链表之类的集合是另一回事。

Dav*_*rtz 8

不,没有任何保证。

虽然我真的应该停在那里,因为它是一个完整的答案,但如果您认为“这怎么可能出错”,请考虑写入非原子变量不是原子的实现。因此,如果您先0x2F写入然后再写入0x30,则另一个线程可能会在写入之前读取第一个半字节,并在写入之后读取第二个半字节并获取0x20

此外,假设一个非原子变量的值为零,并且此代码运行:

#define LAUNCH 1
#define DO_NOT_LAUNCH 0

if (war_has_been_declared)
     non_atomic_variable = LAUNCH;
else
     non_atomic_variable = DO_NOT_LAUNCH;
Run Code Online (Sandbox Code Playgroud)

没有规则禁止实现将代码优化为:

non_atomic_variable = LAUNCH;
if (! war_has_been_declared)
     non_atomic_variable = DO_NOT_LAUNCH;
Run Code Online (Sandbox Code Playgroud)

这意味着即使尚未宣战,另一个线程也可能会看到 LAUNCH 命令!

但重要的是要记住,根本没有任何保证。您是否能想到可能出错的合理方式并不重要。