Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ constructor thread safety

Let's say I have a member variable vector initialised in the constructor, and this vector is read (not written to anywhere else) in several other member functions. Would I need to protect access to the vector (including in the constructor), or is it guaranteed that the object will be fully initialised and flushed to main memory before it's used in other threads?

Let me provide an example:

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
    }
}

Do I need to lock-protect v in A::A(), A::f1() and A::f2()?

like image 205
zhaomin Avatar asked Dec 10 '22 18:12

zhaomin


2 Answers

An object is created by a single thread, so you never have to worry about thread safety when running code inside the constructor that touches member variables. However, if you are using static variables within the constructor then you may need to add some form of locking around the access.

There is an edge case where code within a constructor can be called by multiple threads, and this is when you are using either placement new. For example, let's say you've got a buffer somewhere, and you're going to allocate an object into it:

byte buffer[100];
Foo *foo = new (buffer) Foo;

Here, unless you are locking around the call to new then it's possible for two or more constructors to run in parallel as they're running against the same block of memory. However, this is a real specialized edge-case and would require special handling (eg locking around the placement-new construction).

like image 84
Sean Avatar answered Dec 29 '22 01:12

Sean


An object is constructed by a single thread. Other threads can access the object only by means of the instance reference. In other words, the object's constructor will have finished its work before other threads call a method. You therefore don't need to implement thread-safe code within a constructor.

Of course, in case another object is passed to the constructor as a parameter, eventual access to that object within the constructor, should be thread-safe.

like image 40
Robert Kock Avatar answered Dec 29 '22 01:12

Robert Kock