2013-10-09 40 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