【问题标题】:What's wrong with my simple thread-safe stack?我的简单线程安全堆栈有什么问题?
【发布时间】:2015-05-21 16:58:34
【问题描述】:

以下代码有什么问题?我只是尝试建立一个非常简单的线程安全堆栈,当我运行多个线程同时在堆栈上推送和弹出时,它有时会报告 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_;
};

【问题讨论】:

  • 你的空指针异常发生在哪里?
  • 那么,Stack_stack_ 应该是 Stack_ stack_
  • 您的堆栈副本使用不同的互斥锁(使同步过时)
  • 你得到了对栈顶项的引用,然后调用 pop,它调用了该项的析构函数。
  • @jakebower 它是安全的,它是一个 shared_ptr

标签: c++ multithreading


【解决方案1】:

我看到的主要问题是您没有正确锁定资源。

这个:

lock_guard<mutex>(this->mtx_); // temporary

这将在您锁定后立即解锁,因为它是临时的,并且只存在到;

你应该像这样创建一个命名变量:

lock_guard<mutex> lock(this->mtx_); // lives till end of scope

有关临时对象的信息,请参阅:This Post

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-03-24
  • 2010-10-21
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多