Decipher
Decipher

Reputation: 194

using mutex in c++ concurrency

Try to understand the details of concurrency programming using c++. Came across this piece of code and got stuck with understanding one line of the code. Attached is the details:

template<typename T>
class threadsafe_stack
{

private:
    std::stack<T> data;
    mutable std::mutex m;
public:
    threadsafe_stack(){}
    threadsafe_stack(const threadsafe_stack& other)
    {
    std::lock_guard<std::mutex> lock(other.m);  
    //////////////////why <1>locking other.m not this->m <2> or locking both
    data=other.data;
    }
    // some other codes
}

Upvotes: 0

Views: 207

Answers (1)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48517

This is because the this instance of class threadsafe_stack is being constructed for the first time, so you can be sure noone else is accessing it's fields, so it does not need to use this->mutex. However, someone else can be using the other instance at that time, so it's a good idea to use that mutex to protect other's data field from concurrent access.

That is, the copy constructor, for which the code you see, is invoked on construction of object based on some other instance, e.g.:

threadsafe_stack copy_of_stack{ original_stack };

Now, noone else is able to call a method in context of copy_of_stack instance until the copy-constructor's execution finishes.

The mutex field of each threadsafe_stack is intended to protect from concurrent access the content of the instance that the mutex belongs to.

Now, imagine that there is some other thread that operates on original_stack instance:

while (true)
{
    original_stack.push(123);
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

where the push method looks like this:

void threadsafe_stack<T>::push(const T& value)
{
    std::lock_guard<std::mutex> lock{ this->m };
    data.push(value);
}

As you can see, each push operation protects it's own data field. The same instance of field data is being accessed by copy-constructor of the copy_of_stack instance. Using the same mutex makes the access mutually exclusive in terms of access to data field. In other words: in data = other.data; noone else can be accessing data at this time, but someone can be accessing other.data, this is why we lock only one (that other's) mutex.

Upvotes: 3

Related Questions