2015-05-21 91 views
2

以下代碼有什麼問題?我只是嘗試設置一個非常簡單的線程安全堆棧,當我運行多個線程併發地在堆棧上彈出和彈出時,它有時會報告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_; 
}; 
+0

你的空指針異常在哪裏發生? – Buddy

+2

所以'Stack_stack_'應該是'Stack_ stack_'? – jxh

+0

您的堆棧副本使用不同的互斥鎖(使同步過時) –

回答

7

我看到的主要問題是您沒有正確鎖定您的資源。

此:

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

你鎖定之後,因爲它是一個臨時的,只活直到;這將立即解鎖。

你應該創建一個名爲變量是這樣的:

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

參見:This Post對臨時對象的信息。

+1

也[this](http://kera.name/articles/2012/05/when-is-a-scoped-lock-not-a-scoped-lock/) –

+0

就是這樣,非常感謝! – yangwenjin