2013-11-21 47 views
0

我想通過使用互斥體使類安全線程安全。這是可怕的嗎?可複製的互斥體,以保護類成員

class Container 
{ 
    private: 
    vector<Foo> v; 
    boost::mutex m; 
    public: 
    void add(Foo item) 
    { 
     m.lock(); 
     v.push_back(item); 
     m.unlock(); 
    } 
}; 

的問題是,boost::mutex是不可複製,所以這使得Container不可複製。當然,如果我複製Container,則新實例可能不需要保留與舊的互斥量相同的互斥量 - 它可以擁有自己的新互斥量。我可以爲Container編寫自定義拷貝構造函數,但實際上這是一個複雜的類,我不想。那麼這個怎麼樣:

class CopyableMutex 
{ 
private: 
    boost::mutex m; 
public: 
    CopyableMutex() {} 
    CopyableMutex(CopyableMutex&) {} //don't copy, just create a new one 
    CopyableMutex& operator=(CopyableMutex&) {return *this;} //don't assign, keep it the same 
    void lock() {m.lock();} 
    void unlock() {m.unlock();} 
}; 

...,然後用CopyableMutex更換boost::mutexContainer

這是一件可怕的事情嗎?如果不是,那麼我是否重新發明了輪子 - 有沒有一個圖書館班已經這樣做了?

+2

如果您想要指出所有的C++都是可怕的,那麼您可以用'糟糕的想法'替換'可怕的'(fsvo語法):) –

+0

如果您只需要那個'Container'類中的那個類型,一個私有的嵌套類(沒有濫用可能)。否則,請在* name *中清除它不是可複製的互斥鎖(不滿足'CopyableMutex a; CopyableMutex b(a); assert(a == b);'),而是一個* create-new- on-invoking-copy-mutex *(這是一個可怕的名字;) – dyp

回答

2

是的,它是可怕的。

問題的正確解決方案是您的容器的自定義副本構造函數和賦值運算符。

如果該類「太複雜」來編寫自定義拷貝構造函數,則將線程安全性從容器中分離出來,並使基類容器不包含互斥體,並且可能還有派生類「線程安全容器「,它包含一個互斥體,並具有一個自定義的複製構造函數和賦值操作,只需調用自動生成的基類。

+0

我不知道你是否可以簡潔地告訴我爲什麼這是一個壞主意? –

+0

如果沒有其他,這是完全意想不到的行爲。 –

+0

如果我把它稱爲'UniqueMutex'或者'SpawningMutex'或者什麼的,會更好嗎? –

相關問題