2013-10-09 1 views
5

ブースト1.49で期待どおりに動作するために使用された、スレッドセーフなバウンド待ちキューの次のコードです。ただし、Boost 1.54に更新すると、コードは予期したとおりに実行されなくなります。すなわち、バッファが空(満杯)のとき、コンシューマスレッド(プロデューサスレッド)はm_not_empty(m_not_full)条件変数を永遠に待っていて、起きることはありません(プロデューサスレッドにはミューテックスがないためです)。ブースト1.54でスレッドセーフなバウンドキューがハングする

コードを破損する可能性のあるバージョン1.54にいくつかの変更がありますか?あるいは、私が見逃したコードに間違いがありますか?

#include <iostream> 
#include <boost/circular_buffer.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/thread/condition.hpp> 
#include <boost/thread/thread.hpp> 

template <class T> 
class bounded_buffer { 
public: 
    bounded_buffer(size_t capacity) {cb.set_capacity(capacity);} 
    void push(T item) { 
     boost::mutex::scoped_lock lock(m_mutex); 
     while (cb.full()) { 
      m_not_full.wait(lock); 
     } 
     cb.push_back(item); 
     lock.unlock(); 
     m_not_empty.notify_one(); 
    } 

    void pop(T &pItem) { 
     boost::mutex::scoped_lock lock(m_mutex); 
     while (cb.empty()) { 
      m_not_empty.wait(lock); 
     } 
     pItem = cb.front(); 
     cb.pop_front(); 
     lock.unlock(); 
     m_not_full.notify_one(); 
    } 

private:  
    boost::mutex m_mutex; 
    boost::condition m_not_empty; 
    boost::condition m_not_full; 
    boost::circular_buffer<T> cb; 
}; 

bounded_buffer<int> bb_int(4); 

void producer() { 
    int i = 10; 
    for(int j=0; j<100; ++j) { 
     bb_int.push(i); 
     std::cout << "producer: " << i << std::endl; 
     i++; 
    } 
} 

void consumer() { 
    int i; 
    for(int j=0; j<100; ++j) { 
     bb_int.pop(i); 
     std::cout << "consumer: " << i << std::endl; 
    } 
} 

// Test code 
int main() { 
    // Start the threads. 
    boost::thread consume(consumer); 
    boost::thread produce(producer); 

    // Wait for completion. 
    consume.join(); 
    produce.join(); 
} 
+0

なぜ、_臨界セクション外の条件変数_を通知していませんか?両方の 'lock.unlock()'ステートメントを削除すると、何が起こったか試しましたか? – nosid

+0

@nosid 'lock.unlock()'ステートメントを取り除くと何も変わりません – Alexey

+0

これは掛かっていますよね? – Grzegorz

答えて

2

いいえ、私は間違いを発見しました。私はリリース版でコードをコンパイルしましたが、.libファイルのデバッグ版にリンクしました。基本的には、リリース版ではboost_thread-vc100-mt-gd-1_54.libにリンクされていますが、boost_thread-vc100-mt-1_54.libにリンクする必要があります。

+0

それは不気味な行動です、男! MSのものを使用する人のヒントをありがとう。 – Grzegorz

+0

@Grzegorzはい、私を導くリンクエラーはありませんが、これは見つけにくいエラーでした。ありがとう! – Alexey

関連する問題