2013-10-09 68 views
5

下面的代碼用於在Boost 1.49中按預期工作的有界線程安全隊列。但是,在升級到1.54之後,代碼不再按預期運行。也就是說,當緩衝區爲空(完整)時,消費者線程(生產者線程)正在等待m_not_empty(m_not_full)條件變量,永遠不會喚醒(因爲生產者線程沒有互斥體)。線程安全的有界隊列在Boost中掛起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

爲什麼_notifying_條件變量超出_critical sections_?你有沒有嘗試過會發生什麼,如果你刪除'lock.unlock()'語句? – nosid

+0

@nosid如果我刪除'lock.unlock()'語句,沒有什麼變化 – Alexey

+0

它掛着,對不對? – Grzegorz

回答

2

好的,我發現了一個錯誤。我在發行版中編譯了代碼,但與調試版的.lib文件相關聯。本質上,在發行版本I中鏈接到boost_thread-vc100-mt-gd-1_54.lib,但它應該鏈接到boost_thread-vc100-mt-1_54.lib

+0

這是一個古怪的行爲,男人!感謝那些使用MS軟件的人提示。 – Grzegorz

+0

@Grzegorz是的,沒有鏈接錯誤來指導我,這是一個難以發現的錯誤。謝謝! – Alexey