2011-05-07 23 views
4
class MyClass 
{ 
public: 
    void PushMessage(MyMessage m) // Thread 1 calls this 
    { 
     boost::mutex::scoped_lock lock(mMutex); 
     mQueue.push_back(m); 
     mCondition.notify_one(); 
    } 

    MyMessage PopMessage() 
    { 
     boost::mutex::scoped_lock lock(mMutex); 
     while(mQueue.empty()) 
      mCondition.wait(lock); 

     MyMessage message = mQueue.front(); 
     mQueue.pop_front(); 
     return message; 
    } 

    void foo() // thread 2 is running this loop, and supposed to get messages 
    { 
     for(;;) 
     { 
      MyMessage message = PopMessage(); 

      do_something(message); 
     } 
    } 
private: 
    std::deque<MyMessage> mQueue; 

    boost::mutex mMutex; 
    boost::condition mCondition; 
}; 

私は、コードを実行すると、PushMessageが呼び出され、そしてfoo()PopMessage()に待っているが、PopMessageを返すことはありません。boost mutex、condition、scoped_lock、私はここで間違って使っていますか?

do_somethingはここでは無関係ではないと思います。

私はここで間違っていますか? 不思議なことに、上記のコードはMacで正常に動作しましたが、Linuxで問題があります。
ブーストバージョンは1.44.0

は、私はあなたが1の状態待機のためである1が別のスレッドでメソッド呼び出しを同期させるためである2つのミューテックスオブジェクトを、必要だと思うあなた

+0

「do_something」とは何ですか?誰が 'PushMessage'を呼びますか?このコードは、せいぜい不完全です。 – ildjarn

+1

スレッドライブラリに 'boost :: condition'はありません。あなたは 'boost :: condition_variable'を意味しましたか?書かれているように、そしてその修正を加えれば、あなたのコードはlinuxで1.42のブーストと1.46のブーストで動作します(1.44は手元にありません)。 – Cubbi

答えて

-2

に感謝です。あなたはそれらを混ぜた。

+2

私はそれが正しいとは思わない。ミューテックスは、シグナル/ウェイトと条件セット/コンディションチェックの両方を保護する必要があります。この場合の条件は 'mQueue.empty()'なので、この同じmutexでキューを保護する必要があります。 –

1

のではなく、ロックオブジェクトのスコープは、それがロックを解除する前に、あなたはすなわち、待機中のスレッドのブロックを解除する前に手動でPushMessage()でミューテックスのロックを解除しようとすることができ期限切れに

void PushMessage(MyMessage m) // Thread 1 calls this 
{ 
    boost::mutex::scoped_lock lock(mMutex); 
    mQueue.push_back(m); 

    lock.unlock(); // <== manually unlock 

    mCondition.notify_one(); 
} 

その方法をさせる際に、スレッド2ブロック解除スレッド1にロックが含まれ、スレッド2があなたのミューテックスのロックを取得しようとしている「クロスオーバー」時間はありません。私はなぜそれが問題を引き起こすのか分かりませんが、少なくともスレッド1にはまだロックが含まれていますが、少なくともスレッド2は lock.lock()を呼び出そうとしません。

+0

私は最近これが実際にはもっと複雑であると知りました。ここにリンクがあります: http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/ ありますあなたが話す問題を防ぐ「モーフィング」最適化のようなもの。また、ロックされた状態で通知すると、3つ以上のスレッドを使用する場合に全体的なプログラムがより安全になります。 –

関連する問題