#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();
}
};
问题 data.empty()
如何在以下语句中返回,
if(data.empty()) throw empty_stack();
如果void pop(T& value)
已经锁定了mutex
, #1
。
///已更新///
这是我的理解,
#1
已经锁定互斥锁,当pop(T&value)
返回时将释放。现在,在这个函数的中间,代码调用data.empty()
,然后再次锁定mutex
。由于互斥锁已经被锁定,所以empty
函数无法获得它
这是对std::stack::empty
的调用,而不是thread_safe_stack::empty
。因此,它不会尝试第二次获取互斥锁。