【发布时间】:2018-01-25 03:10:37
【问题描述】:
std::call_once 能否正常工作于非原子变量?考虑以下代码
std::once_flag once;
int x;
void init() { x = 10; }
void f() {
std::call_once(once, init);
assert(x == 10);
}
int main() {
std::thread t1(f), t2(f);
t1.join();
t2.join();
}
init 的副作用在call_once 返回时是否会被所有线程看到? cppreference 上的文档有点模糊。它只说在所有线程上std::call_once 将在init 完成后返回,但没有提到任何阻止 x=10 在init 返回后重新排序的内容。
有什么想法吗?阐明行为的标准在哪里?
【问题讨论】:
-
只有使用 same
std::once_flag的std::call_once调用才是安全的。 -
注意:来自cppreference的
std::call_once的简要定义是“即使从多个线程调用,函数也只调用一次”。这很好解释,不是吗?这是一个很好的问题。 -
std::call_once的第一个参数应该是once而不是once_flag? -
@YSC 调用一次函数是很容易的部分。棘手的问题是它是否在另一个线程已经运行该函数的情况下充当内存屏障。
-
@CodesInChaos 来自同一页面 OP 链接:“在上述所选函数的执行成功完成之前,组中没有调用返回”。我一生中读过不太清晰的文档。
标签: c++ multithreading c++11