2013-02-12 62 views
2

多線程(std::async)通過shared_ptr共享以下類的實例,是否有可能在這部分代碼中出現分段錯誤?如果我的理解std::mutex是正確的,mutex.lock()導致所有其他線程試圖調用mutex.lock()阻塞,直到mutex.unlock()被調用,從而獲得了矢量應該按次序發生。我在這裏錯過了什麼嗎?如果沒有,是否有更好的方式來設計這樣的課程(可能是std::atomic_flag)?多線程課堂互斥分段故障的可能性

#include <mutex> 
#include <vector> 
class Foo 
{ 
    private: 
     std::mutex mutex; 
     std::vector<int> values; 
    public: 
     Foo(); 
     void add(const int); 
     int get(); 
}; 
Foo::Foo() : mutex(), values() {} 
void Foo::add(const int value) 
{ 
    mutex.lock(); 
    values.push_back(value); 
    mutex.unlock(); 
} 
int Foo::get() 
{ 
    mutex.lock(); 
    int value; 
    if (values.size() > 0) 
    { 
     value = values.back(); 
     values.pop_back(); 
    } 
    else 
    { 
     value = 0; 
    } 
    mutex.unlock(); 
    return value; 
} 

免責聲明:0 get()默認值的目的是作爲它在代碼的其餘部分特殊的意義。

更新:上述代碼是完全按照我使用它,除了當然錯字的push_back。

+0

哪裏是賽格故障? – thang 2013-02-12 13:51:02

+3

我沒有看到一個問題,這個類,但你應該使用'lock_guard <>'或'unique_lock <>'來獲取互斥當RAII包裝超出範圍自動釋放。你是在展示整個班級的定義嗎? – 2013-02-12 13:51:59

+1

另外,除了同時訪問這些對象外,你還在做什麼?你是否在複製它們? – 2013-02-12 13:53:01

回答

2

除了不使用RAII獲取鎖並使用size() > 0代替!empty()外,代碼看起來不錯。這就是爲什麼要使用互斥體,這是您需要互斥體的方式和位置的典型例子。

安迪警車指出的那樣,實例無法複製構造或複製分配。

+2

_That會導致編譯時錯誤,應該有人濫用interface._它無論如何也不會編譯,因爲有'的std :: mutex'爲成員從生成默認的拷貝構造函數和賦值運算符阻止。 – Fiktik 2013-02-12 14:04:45

+0

@Fiktik哦,好點。 – 2013-02-12 14:31:35

1

這裏是 「改進」 的版本:

#include <mutex> 
#include <vector> 
class Foo { 
    private: 
     std::mutex mutex; 
     typedef std::lock_guard<std::mutex> lock; 
     std::vector<int> values; 
    public: 
     Foo(); 
     void add(int); 
     int get(); 
}; 
Foo::Foo() : mutex(), values() {} 
void Foo::add(int value) { 
    lock _(mutex); 
    values.push_back(value); 
} 
int Foo::get() { 
    lock _(mutex); 
    int value = 0; 
    if (!values.empty()) 
    { 
     value = values.back(); 
     values.pop_back(); 
    } 
    return value; 
} 

與RAII用於獲取mutex