muduo库源码学习(base)BlockingQueue和BoundBlockingQueue

来源:互联网 发布:apache poi api 编辑:程序博客网 时间:2024/06/05 14:14
#include "./Condition.h"#include "./Mutex.h"#include <boost/noncopyable.hpp>#include <deque>#include <assert.h>namespace muduo{template<typename T>class BlockingQueue : boost::noncopyable//为多线程准备的队列{ public:  BlockingQueue()    : mutex_(),      notEmpty_(mutex_),      queue_()  {  }  void put(const T& x)  {    MutexLockGuard lock(mutex_);    queue_.push_back(x);    notEmpty_.notify(); // wait morphing saves us//pthread_cond_signal后要立刻释放互斥锁?应该是lock析构后才释放吧?    // http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/  }#ifdef __GXX_EXPERIMENTAL_CXX0X__  void put(T&& x)  {    MutexLockGuard lock(mutex_);    queue_.push_back(std::move(x));    notEmpty_.notify();//notify之后不是立刻解锁,而是要等lock析构  }  // FIXME: emplace()#endif  T take()  {    MutexLockGuard lock(mutex_);    // always use a while-loop, due to spurious wakeup    while (queue_.empty())    {      notEmpty_.wait();    }    assert(!queue_.empty());#ifdef __GXX_EXPERIMENTAL_CXX0X__    T front(std::move(queue_.front()));#else    T front(queue_.front());#endif    queue_.pop_front();    return front;  }  size_t size() const  {    MutexLockGuard lock(mutex_);    return queue_.size();  } private:  mutable MutexLock mutex_;  Condition         notEmpty_;  std::deque<T>     queue_;};}#endif  // MUDUO_BASE_BLOCKINGQUEUE_H

// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H#define MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H#include "./Condition.h"#include "./Mutex.h"#include <boost/circular_buffer.hpp>#include <boost/noncopyable.hpp>#include <assert.h>namespace muduo{template<typename T>class BoundedBlockingQueue : boost::noncopyable{ public:  explicit BoundedBlockingQueue(int maxSize)    : mutex_(),      notEmpty_(mutex_),      notFull_(mutex_),      queue_(maxSize)  {  }  void put(const T& x)  {    MutexLockGuard lock(mutex_);    while (queue_.full())    {      notFull_.wait();    }    assert(!queue_.full());    queue_.push_back(x);    notEmpty_.notify();//lockguard对象不能释放没加锁的mutex,所以notify是函数结束后才真正信号有效,那么push_back的顺序又有什么分别呢  }  T take()  {    MutexLockGuard lock(mutex_);    while (queue_.empty())    {      notEmpty_.wait();    }    assert(!queue_.empty());    T front(queue_.front());    queue_.pop_front();    notFull_.notify();    return front;  }  bool empty() const  {    MutexLockGuard lock(mutex_);    return queue_.empty();  }  bool full() const  {    MutexLockGuard lock(mutex_);    return queue_.full();  }  size_t size() const  {    MutexLockGuard lock(mutex_);    return queue_.size();  }  size_t capacity() const  {    MutexLockGuard lock(mutex_);    return queue_.capacity();  } private:  mutable MutexLock          mutex_;  Condition                  notEmpty_;  Condition                  notFull_;  boost::circular_buffer<T>  queue_;};}#endif  // MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H