为什么在以下线程安全堆栈实现中没有死锁?

时间:2011-12-17 05:24:55

标签: c++ multithreading

#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无法获取它。

1 个答案:

答案 0 :(得分:3)

这是对std::stack::empty的致电,而不是thread_safe_stack::empty。所以它不是第二次尝试获取互斥锁。