Ring Buffer (circular Buffer)环形缓冲区简介 (二)

2014-11-24 02:34:43 · 作者: · 浏览: 17
ype::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits::param_type param_type;

explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}

void push_front(boost::call_traits::param_type item) {
// 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::is_not_full, this));
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::is_not_empty, this));
*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 container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename boost::call_traits::param_type param_type;

explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}

void push_front(boost::call_traits::param_type item) {
// 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::is_not_full, this));
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::is_not_empty, this));
*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中读取下一