尝试了解使用 C++ 进行并发编程的细节。遇到这段代码并无法理解一行代码。附件是详细信息:
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
}
最佳答案
这是因为 threadsafe_stack
类的 this
实例是第一次构造,所以你可以确定没有其他人正在访问它的字段,所以它不会需要使用 this->mutex
。但是,当时其他人可能正在使用 other
实例,因此最好使用该互斥锁来保护 other
的 data
来自并发访问的字段。
也就是说,您看到的代码的复制构造函数是在基于其他实例构造对象时调用的,例如:
threadsafe_stack copy_of_stack{ original_stack };
现在,在复制构造函数的执行完成之前,没有其他人能够在 copy_of_stack
实例的上下文中调用方法。
每个 threadsafe_stack
的互斥量字段旨在防止并发访问互斥量所属实例的内容。
现在,假设有一些其他线程在 original_stack
实例上运行:
while (true)
{
original_stack.push(123);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
push
方法如下所示:
void threadsafe_stack<T>::push(const T& value)
{
std::lock_guard<std::mutex> lock{ this->m };
data.push(value);
}
如您所见,每个push
操作都会保护它自己的 data
字段。 copy_of_stack
实例的复制构造函数正在访问字段 data
的相同实例。使用相同的互斥锁 使得访问在访问data
字段方面互斥。换句话说:在 data = other.data;
此时没有其他人可以访问 data
,但是有人可以访问 other.data
,这就是为什么我们只锁定一个(那个 other
的)互斥体。
关于c++ - 在 C++ 并发中使用互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25475844/