阻塞队列实现

0 前言

      阻塞队列在生产业务的很多场景里,都有使用的需要。例如:在数据流式处理服务中,我们需要异步的执行上游逻辑a与下游逻辑b;在rpc网络通讯框架场景中,我们需要解耦网络读写线程与消息处理线程。总之, 阻塞队列是在不同职责的线程之间进行数据沟通的桥梁。在jdk里面有现成的BlockingQueue类,现在让我们看看一个C++版的实现吧: 

1 实现源码

   1.1 锁封装

    通过信号量保证不同线程之间数据操作的一致性。

class CSemaphore

{

 public:

  CSemaphore()

  {

    sem_init(&m_sem, 0, 0);

  }

 

  ~CSemaphore()

  {

    sem_destroy(&m_sem);

  }

 

  void Produce()

  {

    sem_post(&m_sem);

  }

 

  void Consume()

  {

    while (sem_wait(&m_sem) != 0)

    {

      sched_yield();

    }

  }

 

  bool Try()

  {

    int value = 0;

    int ret = sem_getvalue(&m_sem, &value);

    if(ret < 0 || value <= 0)

    {

      return false;

    }

    return true;

  }

 

  bool TryTime(int micSec)

  {

    struct timespec ts;

    clock_gettime(CLOCK_REALTIME,&ts);

    if(micSec >= 1000000)

      ts.tv_sec += micSec/1000000;

    ts.tv_nsec += micSec%1000000*1000;

    if(ts.tv_nsec >= 1000000000)

    {

      ++ts.tv_sec;

      ts.tv_nsec -= 1000000000;

    }

 

    int ret = sem_timedwait(&m_sem,&ts);

    if(ret < 0)

      return false;

    return true;

  }

 

  int GetCount()

  {

    int value = 0;

    int ret = sem_getvalue(&m_sem, &value);

    if(ret < 0)

      return -1;

    else

      return value;

  }

 private:

  sem_t  m_sem;

};
View Code

   1.2 写数据(消息)   

  bool Put(const __T& value)
  {

    CMutexLock lock(m_mutex);

    if(m_queue.size() > m_queMax)

    { 

      return false;

    } 

    m_queue.push_back(value);

    m_semaphore.Produce();

    return true;

  }

   1.3 读取数据(消息)    

  bool Get(__T& value)
  {

    m_semaphore.Consume();

    CMutexLock lock(m_mutex);

    if(m_queue.empty())

      return false;

    value = m_queue.front();

    m_queue.pop_front();

    return true;

  }

2 实例

2.1 源码

2.2 输出 

thread id : 139737310840576 output is: 557

thread id : 139737310840576 output is: 558

thread id : 139737310840576 output is: 559

thread id : 139737310840576 output is: 560

thread id : 139737310840576 output is: 561

thread id : 139737310840576 output is: 562

thread id : 139737310840576 output is: 563

thread id : 139737310840576 output is: 564

thread id : 139737310840576 output is: 565

thread id : 139737300350720 output is: 566

thread id : 139737300350720 output is: 567

thread id : 139737300350720 output is: 568

thread id : 139737300350720 output is: 569

thread id : 139737300350720 output is: 570

thread id : 139737310840576 output is: 571

  源码请见附件 https://files.cnblogs.com/files/gisorange/blockqueue.zip

 

posted @ 2015-10-19 10:13  gisorange  阅读(393)  评论(0编辑  收藏  举报