C++ 构造函数线程安全

zha*_*min 4 c++ multithreading thread-safety c++11

假设我在构造函数中初始化了一个成员变量向量,并且在其他几个成员函数中读取(未写入其他任何地方)该向量。我是否需要保护对向量的访问(包括在构造函数中),还是保证该对象在其他线程中使用之前将被完全初始化并刷新到主内存?

让我举个例子:

class A
{
public:
    A();
    void f1();
    void f2();
private:
    std::vector<int> v;
};

A::A()
{
    // do some setup work in v
    v.push_back(1);
}

// called from thread1
void A::f1()
{
    // some readonly work on v
    for (auto i : v) {
        // do something on i
    }
}

// called from thread2
void A::f2()
{
    // more readonly work on v
    if (v.empty()) {
        // do other work
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要在锁保护v A::A()A::f1()A::f2()

Sea*_*ean 8

对象是由单个线程创建的,因此在构造函数中运行涉及成员变量的代码时,您永远不必担心线程安全。但是,如果您在构造函数中使用静态变量,那么您可能需要在访问周围添加某种形式的锁定。

存在一种极端情况,构造函数中的代码可以被多个线程调用,这就是您使用placement new. 例如,假设您在某处有一个缓冲区,并且您将向其中分配一个对象:

byte buffer[100];
Foo *foo = new (buffer) Foo;
Run Code Online (Sandbox Code Playgroud)

在这里,除非您锁定对 的调用,否则new两个或多个构造函数可能会并行运行,因为它们针对同一块内存运行。然而,这是一个真正的特殊边缘情况,需要特殊处理(例如,在放置新结构周围锁定)。