创建/加入线程时的隐式同步

时间:2015-04-16 19:34:39

标签: c++ multithreading language-lawyer memory-model

考虑到创建/加入线程时隐含的同步,x类型要求此代码工作所需的最小框架是什么:std::atomicvolatile?什么?

#include <thread>
#include <cassert>
int main() {
    int x = 123; // ***
    std::thread( [ & ] { assert( x == 123 ); x = 321; } ).join();
    assert( x == 321 );
    return 0;
}

1 个答案:

答案 0 :(得分:11)

std::thread的构造函数的调用是同步的,并且在调用线程函数的副本(30.3.1.2/6)之前发生。

thread::join给出了类似的同步保证:线程的完成发生在join返回之前(30.3.1.4/7)。

您的代码会创建一个线程并立即加入它。尽管您的lambda通过引用捕获,但没有并发(代码按顺序运行),std::thread提供的保证确保您不需要任何特殊的框架来保护x。断言永远不会失败。

假设您的代码段不同,因此您实际上具有某种类型的并发访问权限,则必须使用std::atomic或互斥锁。 volatile最明确地不够(除非是巧合)。