[英]Why there is no dead-lock in the following thread-safe stack implementation?
#include <exception>
struct empty_stack: std::exception
{
const char* what() const throw();
};
template<typename T>
class thread_safe_stack
{
private:
std::stack<T> data;
mutable std::mutex m;
public:
stack(){}
stack(const stack& other)
{
std::lock_guard<std::mutex> lock(other.m);
data=other.data;
}
stack& operator=(const stack&) = delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
std::shared_ptr<T> const res(new T(data.top());
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m); // #1
if(data.empty()) throw empty_stack();
value=data.top();
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
Question How can the data.empty()
return in the following statement, 问题
data.empty()
如何在以下语句中返回,
if(data.empty()) throw empty_stack();
given the void pop(T& value)
has locked the mutex
already #1
. 给定
void pop(T& value)
已将mutex
锁定为#1
。
/// Updated /// /// 更新 ///
Here is my understanding, 这是我的理解,
#1
already lock the mutex and will release when the pop(T&value)
returns. #1
已经锁定了互斥锁,并且将在pop(T&value)
返回时释放。 Now in the middle of this function, the code calls data.empty()
which in turn locks the mutex
again. 现在,在此函数的中间,代码将调用
data.empty()
,从而再次锁定mutex
。 Since the mutex has been locked, so the function empty
cannot get it. 由于互斥锁已被锁定,因此
empty
函数无法获取它。
That's a call to std::stack::empty
, not thread_safe_stack::empty
. 那是对
std::stack::empty
的调用,而不是thread_safe_stack::empty
的调用。 So it isn't trying to acquire the mutex a second time. 因此,它并不是第二次尝试获取互斥量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.