本文共 2234 字,大约阅读时间需要 7 分钟。
size:队列的大小;2个信号量:semFull(size)表示初始状态队列是空的,可以生产的产品个数=size;semEmpty(0)表示初始状态队列是空的,可以消费的产品个数=0;生产者线程如何操作队列?//生产者p(semFull)//若队列不满,则可以生产产品,直到生产满了,那么p(semFull)操作就会阻塞;queue.push(x)//一旦生产了一个产品,队列就不为空了,有产品可以消费了,通知消费者线程可以消费了;v(semEmpty)//消费者//若队列中没有产品可以消费,则p(semEmpty)则会阻塞p(semEmpty)x = queue.pop()//消费完产品则会腾出一个新的空间,能容纳新的产品v(semFull)若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutex//生产者p(semFull)lock(mutex)queue.push(x)unlock(mutex)v(semEmpty)//消费者p(semFull)lock(mutex)queue.push(x)unlock(mutex)v(semFull)
无界的话,则不需要判断队列是否已经是满的若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutex//生产者lock(mutex)queue.push(x)unlock(mutex)v(semEmpty)//消费者p(semFull)lock(mutex)queue.push(x)unlock(mutex)
无界的话,则不需要判断队列是否已经是满的若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutexnotEmpty是条件变量//生产者lock(mutex)queue.push(x)unlock(mutex)//向消费者线程发起通知,可以消费产品了,队列不为空了notEmpty.signal()//消费者//等待条件变量,等待队列不为空,队列为空,则需要等待//不用if,防止虚假唤醒while(queue.empty()){ notEmpty.wait()//生产者一旦生产产品notEmpty.signal(),队列就不为空了,等待将被唤醒}lock(mutex)queue.push(x)unlock(mutex)
有界的话,则需要判断队列是否已经是满的sizesemFull(size)semEmpty(0)mutexnotEmpty,notFull是条件变量//生产者//队列已经满了需要等待条件满足while(queue.Full()){ notFull.wait();}lock(mutex)queue.push(x)unlock(mutex)//向消费者线程发起通知,可以消费产品了,队列不为空了notEmpty.signal()//消费者//等待条件变量,等待队列不为空,队列为空,则需要等待//不用if,防止虚假唤醒while(queue.empty()){ notEmpty.wait()//生产者一旦生产产品notEmpty.signal(),队列就不为空了,等待将被唤醒}lock(mutex)queue.push(x)unlock(mutex)//消费一个产品,意味着队列不满notFull.signal()
eg:src\15\jmuduo\muduo\base\BlockingQueue.h
eg测试:src\15\jmuduo\muduo\base\tests\BlockingQueue_test.cc
测试:生产者添加了产品,时间片恰好切换到了消费者线程,所以造成了消费者线程先打印了。一般情况都是消费者线程后打印才对。
eg测试:src\15\jmuduo\muduo\base\tests\BlockingQueue_bench.cc
src\15\jmuduo\muduo\base\tests\CMakeLists.txt测试:
类图
环形缓冲区circular_buffer
头部表示读的位置,尾部表示写的位置; 写的指针不能赶上都的指针; 缓冲区写满了,则不应该再写了,加入1号产品被消费走了,则我才可以继续写;eg:src\15\jmuduo\muduo\base\tests\BoundedBlockingQueue_test.cc
eg测试:src\15\jmuduo\muduo\base\tests\BoundedBlockingQueue_test.cc
测试:生产到20个产品就阻塞了,使得消费者得去消费产品,生产者才可以继续生产产品
转载地址:http://bmiws.baihongyu.com/