2013-04-24 5 views
8

私はこのようなコンストラクタでコンテナを提供し、ユーザーに基づいていますConcurrentQueueクラス...イニシャライザのリストにミューテックスをロックする方法はありますか?

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) {} 

を持っている。しかし、私はそれがコピーされている間otherのミューテックスをロックする必要があります。

オプション1:

だから私はすべてでコピーコンストラクタを使用して、行うことができませんでした...

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) 
{ 
    std::lock_guard<std::mutex> lock(other.m_Mutex); 
    m_Queue = other.m_Queue; 
} 

しかし、私はそのコピーの割り当てを保証し、建設をコピーすることはできませんが等価です機能性。

オプション2:

私はプライベートメソッドを持つことができ

...

std::queue<T, Container> GetQueue() const 
{ 
    std::lock_guard<std::mutex> lock(other.m_Mutex); 
    return m_Queue; 
} 

そしてコンストラクタでこれを行う...

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.GetQueue()) {} 

しかし、この潜在的に(最適化に依存します)は、m_Queueのコピーコンストラクタを一度使用し、そのコンストラクタを一度使用します。また、コピーと移動が単なるコピーと同等であることを保証することはできません。さらに、ユーザが提供するコンテナは、奇妙でコピー可能であるが移動不能である可能性があり、このアプローチにも問題が生じる可能性がある。

どうすればいいですか?

答えて

9
ConcurrrentQueue::ConcurrrentQueue(
     ConcurrrentQueue const& other) 
    : m_Queue((std::lock_guard<std::mutex>(other.m_Mutex), 
       other.m_Queue)) 
{ 
} 

が有効です。

+0

いつもそうするべきだと思いますか? – 0x499602D2

+0

@ 0x499602D2実際、私はその状況を避けるべきだと思います。私はあなたの実際の文脈や解決しようとしている問題を他の解決法を提案するのには十分に分かっていませんが、実際にこのようなものを実際に使う必要はなかったことは分かっています。実際には、スレッド間でコンテナをコピーしたケースは考えられません。 –

1

コンテンツのコピーを作成し、メンバーと交換します。少なくともそれは最も簡単で、IMHOで最もクリーンな方法です。クリーンな方法はコンマを使用することです。(a, b)bですが、aがスコープロックの場合は、次のシーケンスポイントまで有効です。bを使用してローカルコピーを初期化します。

、請求、考慮すべき二つのものがあります。

  • たぶんコピーが、とにかく、このようなスマートな考えではありませんし、あなただけのコピーを無効にする場合は、あなたのデザインが同様に動作します。
  • キューにアクセスでき、それを読み取ってコピーできる場合は、そのミューテックスが既にロックされていなければならないことを意味しませんか?そうでない場合は、本当にキューをコピーしたいと思いますか?私はデザインを正当化する答えがあることは疑問ではありませんが、それは珍しいことです。
関連する問題