生产者消费者问题

C++11多线程入门(10)——生产者消费者问题

    1、问题描述

    生产者生产产品并放入“缓冲池”(店铺)中,消费者来到店铺购买产品并且取走。消费者也许有很多,购买的产品也许会很多,那么缓冲池(店铺)不见得能存放足够的产品,足够的多产品应该在生产者的货仓里,而不是在店铺。同样的,消费者如果购买的很多有可能是批发商、经销商,也有自己的仓库。产品从生产者的仓库流向消费者的仓库如同沙漏,最窄的区域就是缓冲池。

2、条件限制

    缓冲池空的时候,消费者不得购买(因为没有产品了),缓冲池满了的时候,生产者不得投放(因为放不下了),他们需要在这两种情况下等待对方购买拿走或投放补充。

    生产者将仓库里所有产品投放到缓冲池之后就可以结束了。

    消费者拿走所有的产品之后也可以结束了。

3、头文件及程序描述区域

生产者消费者问题_第1张图片

ProducerAndConsumer.h

4、确定数据结构

     产品是有数的,投放一个,生产者仓库就少一个,缓冲池当前产品数量就多一个;拿走一个,缓冲池当前产品数量就少一个,消费者仓库产品数量就多一个。

    因此采用C++标准库(STL)队列结构(queue):

    #include

    queue buffer ;

5、确定异步操作

    (1)生产者与消费者需要互相通知,告知对方取走或补货,因此需要两个条件变量:

    #include

    condition_variable notEmpty , notFull ;

   (2) 互斥量也必不可少:

    #include

    mutex MyMutex ;

    (3)消费者之间也要相互通知,在确定售完的情况下离开,不再等待

    bool Stop ;

    (4)同步反映当前缓冲池内产品数量

    int CurrentAmount ;

生产者消费者问题_第2张图片

ProducerAndConsumer.h

6、确定线程区

(1)群体数据区

    生产者货仓、消费者货仓、生产者线程区、消费者线程区、缓冲池

(2)个体数据区

    缓冲池容限、产品总数、末尾产品标志

(3)线程函数

    生产者函数、消费者函数、启动函数

生产者消费者问题_第3张图片

ProducerAndConsumer.h

(4)构造函数与析构函数

生产者消费者问题_第4张图片

ProducerAndConsumer.h

(5)线程函数声明、设置末尾产品标识

生产者消费者问题_第5张图片

ProducerAndConsumer.h

(6)消费者函数

生产者消费者问题_第6张图片

ProducerAndConsumer.h

(7)生产者函数

生产者消费者问题_第7张图片

ProducerAndConsumer.h

(8)启动函数

生产者消费者问题_第8张图片

ProducerAndConsumer.h

(9)主函数

生产者消费者问题_第9张图片

ProducerAndConsumer.cpp

运行结果:

生产者消费者问题_第10张图片

7、关于cv_status的重写

    由于程序中调用了wait_for函数的三参数版本,返回值为bool型,故而不便于判断是否超时,特重写enum cv_status:

    于是可以比较方便的编写:

生产者消费者问题_第11张图片

生产者消费者问题_第12张图片

结语:本例适用“单生产者-多消费者”问题的解决。

(参考网站:CSDN、cppreference.com、cplusplus.com等)

(参考书目:《深入理解C++11》、《深入应用C++11》等)

你可能感兴趣的:(c++)