typedef typename container_type::value_type value_type;
typedef typename boost::call_traits
explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}
void push_front(boost::call_traits
// param_type represents the "best" way to pass a parameter of type value_type to a method
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer
m_container.push_front(item);
++m_unread;
lock.unlock();
m_not_empty.notify_one();
}
void pop_back(value_type* pItem) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&bounded_buffer
*pItem = m_container[--m_unread];
lock.unlock();
m_not_full.notify_one();
}
private:
bounded_buffer(const bounded_buffer&); // Disabled copy constructor
bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator
bool is_not_empty() const { return m_unread > 0; }
bool is_not_full() const { return m_unread < m_container.capacity(); }
size_type m_unread;
container_type m_container;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
};
#include
#include
#include
#include
#include
#include
#include
template
class bounded_buffer {
public:
typedef boost::circular_buffer
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits
explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}
void push_front(boost::call_traits
// param_type represents the "best" way to pass a parameter of type value_type to a method
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&bounded_buffer
m_container.push_front(item);
++m_unread;
lock.unlock();
m_not_empty.notify_one();
}
void pop_back(value_type* pItem) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&bounded_buffer
*pItem = m_container[--m_unread];
lock.unlock();
m_not_full.notify_one();
}
private:
bounded_buffer(const bounded_buffer&); // Disabled copy constructor
bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator
bool is_not_empty() const { return m_unread > 0; }
bool is_not_full() const { return m_unread < m_container.capacity(); }
size_type m_unread;
container_type m_container;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
};
1. push_front() 方法被生产者线程调用,目的是插入新元素到buffer中。这个方法会锁住mutex,一直等到有新空间可以插入新元素。 (Mutex锁在等待期间是没有锁住的,只有条件满足的时候才会把锁锁上) 假如在buffer中有一个可用的空间,执行就会继续,该方法就会插入元素进入到环形缓冲区的末尾。 然后未读元素的数量就会增加,然后自动解锁。 (在例子中,Mutex锁解锁是会抛出一个异常,锁会在scoped_lock对象的析构函数中自动被打开). 最后,这个方法会通知其中的一个消费者线程,告诉他们,有一个新的元素插入了缓冲区。
2. pop_back() 方法被消费者线程调用,目的是为了从buffer中读取下一