考虑以下两个执行线程:
主题A:
// Initialize stuff...
std::atomic<bool> interrupted = false;
// Launch thread B
// ... Do some useful stuff
// Interrupt B
interrupted = true;
InterruptMessageLoop(B);
主题B
RunMessageLoop(); // Can exit by itself or due to InterruptMessageLoop
if (interrupted) {
// Do something special
}
我的问题是 - 我可以确定,如果线程A确实调用了InterruptMessageLoop,线程B会看到interrupted
状态的true
原子吗? (我将此称为“期望的行为”)
我在这里看到的问题是,如果我理解正确的话,原始变量的std::memory_order_seq_cst
中使用的operator=
的内存排序可以保证没有正常的写入将在原子操作之后重新排序,并且在原子操作之前不会重新排序正常的读取 。但是可能会发生线程A在原子之前重新排序InterruptMessageLoop(B)
,然后线程B中断消息循环并读取interrupted
的不正确(关于我想要的逻辑)值,然后只有线程A写入interrupted
。那是对的吗?如果是,有没有办法确保我得到我想要的行为而不诉诸互斥量(即将InterruptMessageLoop和布尔修改包装成互斥锁并在读取时锁定相同的互斥锁)?
请注意,我无法控制RunMessageLoop
的实施。
修改 请注意,当我发出命令来中断循环并且循环正常存在时(忽略我的命令) - 在我的情况下,线程B认为中断导致消息循环退出是很好的。
答案 0 :(得分:0)
要准确区分RunMessageLoop是正常完成还是由于InterruptMessageLoop,您必须依赖RunMessageLoop告诉您的某种状态。
你想做的hacky方式是行不通的。假设您设法保证编译器不记录任何内容。您仍然有以下交错: