Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safe bounded queue hangs in Boost 1.54

The following code for bounded thread-safe queue used to work as expected in Boost 1.49. However, after updating to Boost 1.54 the code no longer runs as expected. Namely, when the buffer is empty (full), the consumer thread (producer thread) is waiting forever for m_not_empty (m_not_full) conditional variable and never wakes up (I think because the producer thread doesn't have the mutex).

Are there some changes in version 1.54 that could break the code? Or, maybe, there are mistakes in the code that I missed?

#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();
}
like image 556
Alexey Avatar asked Oct 09 '13 19:10

Alexey


1 Answers

Ok, I found a mistake. I compiled the code in release version but linked to debug version of .lib file. Essentially, in release version I linked to boost_thread-vc100-mt-gd-1_54.lib but it should be linked to boost_thread-vc100-mt-1_54.lib.

like image 70
Alexey Avatar answered Oct 01 '22 19:10

Alexey