【发布时间】:2021-03-24 02:32:31
【问题描述】:
正如我们所知,编译器或 CPU 可以根据需要重新排序执行,前提是它们遵循 as-if 规则。例如,如果我们有这样一段代码:
C = A + B;
D = E + F;
编译器或 CPU 可能会在 C = A + B 之前执行 D = E + F。我能理解。
现在让我们谈谈另一个案例。
说我有两个线程a 和b。我想在执行时设置一些标记,以便我可以监控a和b的整个过程。
queue q; // thread safe
void thread_a()
{
// do something
q.push("a - 1");
// do something
q.push("a - 2");
}
void thread_b()
{
// do something
q.push("b - 1");
// do something
q.push("b - 2");
}
我的问题是:既然我们有as-if规则并且执行顺序可能会重新排序,那是否意味着q中的消息不可靠?这意味着真正的执行顺序是a - 1、b - 1、b - 2 和a - 2 但在q 中可能有a - 1、a - 2、b - 1 和b - 2?如果发生这种情况,我应该如何设计或使用哪种技术来监控多线程的进程?
【问题讨论】:
-
只是为了检查:你说
queue q;是线程安全的。你知道std::queueis not thread safe,对吧?使用锁定(或无锁原子)的实际线程安全队列几乎肯定会强制执行排序约束(至少是获取/释放语义),这会抑制任意重新排序。 -
我有点怀疑两个推送都可以以这种方式重新排序。你能举一个这样的小说的例子吗
queue这是真的吗? -
@SamVarshavchik 这有关系吗?确实存在一些线程安全队列,对吧?或者我们可以在这两个函数中使用互斥锁。您是在告诉我这两个函数中的线程安全队列或互斥锁会禁止重新排序吗?
-
如果队列不是线程安全的,那么另一个线程可以观察到没有条目的大小为 2 的队列。或者只有两个条目之一。
-
您需要定义
real execution order是什么。给定示例中的源代码行都不是原子操作(even 在线程安全实现中)。完全有可能在q.push("a - 1");开始之前执行到q.push("b - 1");,但在结束后返回。
标签: c++ multithreading c++11 instruction-reordering as-if