c++ - C++ 线程安全:如果只有一个线程可以写入非原子变量但多个线程从中读取.. 会遇到问题吗?
问题描述
如果一个线程读取另一个线程正在写入的非原子原始变量,它是否保证在写入之前或之后读取该值,或者它可以在写入期间以某种方式读取一些损坏的版本?
我意识到像链表这样的集合是另一回事。
解决方案
不,没有任何保证。
虽然我真的应该停在那里,因为这是一个完整的答案,但如果您认为“这怎么可能出错”,请考虑一个对非原子变量的写入不是原子的实现。因此,如果您先0x2F
write 然后 write 0x30
,则另一个线程可能会在 write 之前读取第一个 nibble,然后在 and get 之后读取第二个 nibble 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;
没有规则禁止实现将代码优化为:
non_atomic_variable = LAUNCH;
if (! war_has_been_declared)
non_atomic_variable = DO_NOT_LAUNCH;
这意味着即使尚未宣战,另一个线程也可能会看到 LAUNCH 命令!
但重要的是要记住,根本没有任何保证。你是否能想出一个可能出错的合理方法并不重要。
推荐阅读
- windows - 从行为类似于键盘的 USB HID 设备读取
- jpeg - 错误“不是 JPEG 文件:以 0x00 0x00 开头”
- swift - 每次调用一个值时创建一个循环以添加 40
- javascript - Jasmine 测试超时并显示“在 5000 毫秒内未调用异步回调”尽管在我的 Angular 项目测试中没有使用异步函数
- javascript - 如果将对象作为参数传递给另一个文件中的函数,原始对象会改变吗?
- java - Thread 对象的 run 方法如何在内部调用 Runnable 对象的 run 方法?
- angular - 在 mat-cell 中使用 ngFor 的正确方法
- microservices - Api 网关如何将响应组合成微服务
- c++ - 如何使用 TouchGFX 在 LCD 屏幕上显示 ADC 值?
- haskell - haskell中的数字转换