下面的代码有什么问题?我只是尝试建立一个相当简单的线程安全堆栈,当我运行几个线程并发地在堆栈上push和pop时,它有时会报告0xC0000005异常。
#include <stack>
#include <list>
#include <memory>
#include <mutex>
template<class T> class Stack{
typedef stack < shared_ptr<T>, list<shared_ptr<T>>> Stack_;
public:
Stack(){}
Stack(const Stack& other){
lock_guard<mutex>(other.mtx_);
stack_ = other.stack_;
}
void push(shared_ptr<T> value){
lock_guard<mutex>(this->mtx_);
stack_.push(value);
}
shared_ptr<T> pop(){
lock_guard<mutex>(this->mtx_);
if (stack_.empty()) return nullptr;
auto res = stack_.top();
stack_.pop();
return res;
}
private:
mutex mtx_;
Stack_ stack_;
};
我看到的主要问题是您没有正确地锁定资源。
:
lock_guard<mutex>(this->mtx_); // temporary
它将在你锁定它之后立即解锁,因为它是一个临时的,只存在于;
。
你应该创建一个像这样的命名变量:
lock_guard<mutex> lock(this->mtx_); // lives till end of scope
参见:这篇文章关于临时对象的信息