习题:假设
有10个生产者和10个消费者
初始物品100个
生产者一次生产一件物品 消费者一次消费一件物品
生产者每生产一件物品 消费者就消费掉一件
消费者每消费掉一件 生产者就生产一件物品
直到这样交互100次
思想 :10个消费者为一个线程池 10个生产者为一个线程池
消费者任务 物品--;
生产者任务 物品++;
这里有个条件
1.
每次执行 物品--; 或 物品++;时 我们只想让一个生产者或消费者去执行 其他的人等待 所以这里我们用到了互斥量 同一时刻只允许一个线程执行
2.
生产者一次生产一件物品 消费者一次消费一件物品
生产者每生产一件物品 消费者就消费掉一件
这我们可以利用互斥量的信号的获取和释放来实现
当生产者获取到生产者的互斥量信号 它生产一件物品 然后释放掉消费者的互斥量信号
消费者获取到消费者的互斥量信号 它消费一件物品 然后释放掉生产者的互斥量信号
如此往复
完整代码如下
生产者消费者类的声明
- #ifndef CREATER_H
- #define CREATER_H
- #include
- #include
- #include
-
- class CreaterConsumer
- {
- private:
- //生产者句柄
- HANDLE m_Create;
- //消费者句柄
- HANDLE m_Consumer;
- //生产者线程链表
- std::list
m_myCreaterlist; - //消费者线程链表
- std::list
m_myConsumerlist; - //产品数量
- long product;
- //生产者互斥量
- HANDLE m_MutexCreater;
- //消费者互斥量
- HANDLE m_MutexConsumer;
- public:
- //记录交互次数
- long nCount;
- public:
- CreaterConsumer();
- ~CreaterConsumer();
- //创建生产者线程池
- bool CreateThreadPool();
- //创建消费者线程池
- bool ConsumerThreadPool();
- //销毁生产者线程池
- void DeleteCreaterThreadPool();
- //销毁消费者线程池
- void DeleteConsumerThreadPool();
- //生产者线程函数
- static DWORD WINAPI CreateThreadProc(LPVOID lpvoid);
- //消费者线程函数
- static DWORD WINAPI ConsumerThreadProc(LPVOID lpvoid);
- };
-
- #endif // CREATER_H
生产者消费者类的的定义
- #include "creater.h"
- #include
- using namespace std;
- CreaterConsumer::CreaterConsumer()
- {
- m_Create=NULL;
- m_Consumer=NULL;
- product=100;
- m_MutexCreater=CreateMutex(0,0,0);
- m_MutexConsumer=CreateMutex(0,1,0);//开始先让消费者启动交互
- nCount=0;
-
- }
-
- CreaterConsumer::~CreaterConsumer()
- {
-
- }
- bool CreaterConsumer::CreateThreadPool()
- {
- //创建十个线程到生产者线程列表中去
- for(int i=0;i<10;i++)
- {
- m_Create=CreateThread(0,0,&CreateThreadProc,this,0,0);
- if(m_Create)
- {
- m_myCreaterlist.push_back(m_Create);
- }
- }
-
-
- }
-
- bool CreaterConsumer::ConsumerThreadPool()
- {
- //创建十个线程到消费者线程列表中去
- for(int i=0;i<10;i++)
- {
- m_Consumer=CreateThread(0,0,&CreateThreadProc,this,0,0);
- if(m_Consumer)
- {
- m_myConsumerlist.push_back(m_Consumer);
- }
- }
- }
-
- DWORD WINAPI CreaterConsumer::CreateThreadProc(LPVOID lpvoid)
- {
- CreaterConsumer* pthis=(CreaterConsumer*)lpvoid;
- while(1)
- {
- //当前交互次数小于100
- if(pthis->nCount<100)
- {
- WaitForSingleObject(pthis->m_MutexCreater,INFINITE);
- //当交互次数为 例如:99 时 进来了多个线程
- //如果一个交互次数为99 的线程执行完 交互次数变为100 应该不继续执行
- //但是剩下的进来的这些线程不会出去 会继续执行 交互次数就会大于100 所以加了一个筛选 if(pthis->nCount>=100)
-
- if(pthis->nCount>=100)
- {
- //如果此时交互次数>=100 剩下的进来的线程不会继续执行 而是会被筛选出去
- ReleaseMutex( pthis->m_MutexConsumer);
- continue;
- }
- //pthis->product++;
- //物品数++
- InterlockedIncrement(&pthis->product);
- //交互次数++
- InterlockedIncrement(&pthis->nCount);
- //打印交互次数
- cout<
nCount< - //释放消费者信号
- ReleaseMutex(pthis->m_MutexConsumer);
- }
-
- }
-
- }
-
- DWORD WINAPI CreaterConsumer::ConsumerThreadProc(LPVOID lpvoid)
- {
- CreaterConsumer* pthis=(CreaterConsumer*)lpvoid;
- while(1)
- {
- if(pthis->nCount<100)
- {
- WaitForSingleObject(pthis->m_MutexConsumer,INFINITE);
- if(pthis->nCount>=100)
- {
- ReleaseMutex( pthis->m_MutexCreater);
- continue;
- }
- //pthis->product--;
- //物品数--;
- InterlockedDecrement(&pthis->product);
- //释放生产者信号
- ReleaseMutex(pthis->m_MutexCreater);
- }
-
-
-
- }
-
-
-
- }
-
-
- void CreaterConsumer::DeleteCreaterThreadPool()
- {
- //遍历生产者列表
- auto ite= m_myCreaterlist.begin();
- //将生产者列表的每一项都删除
- while(ite!=m_myCreaterlist.end())
- {
- delete *ite;
- ite++;
- }
- //清空列表
- m_myCreaterlist.clear();
-
- //释放生产者线程句柄
- if(m_Create)
- {
- CloseHandle(m_Create);
- m_Create=NULL;
- }
- //释放生产者互斥量
- if(m_MutexCreater)
- {
- CloseHandle(m_MutexCreater);
- m_MutexCreater=NULL;
- }
- }
-
- void CreaterConsumer::DeleteConsumerThreadPool()
- {
- //遍历并删除消费者列表的每一项
- auto ite= m_myConsumerlist.begin();
- while(ite!=m_myConsumerlist.end())
- {
- delete *ite;
- ite++;
- }
- //清空消费者列表
- m_myConsumerlist.clear();
-
- //释放消费者线程句柄
- if(m_Consumer)
- {
- CloseHandle(m_Consumer);
- m_Consumer=NULL;
- }
- //释放消费者互斥量
- if(m_MutexConsumer)
- {
- CloseHandle(m_MutexConsumer);
- m_MutexConsumer=NULL;
- }
-
- }
主函数
- #include "creater.h"
- #include
- using namespace std;
- CreaterConsumer::CreaterConsumer()
- {
- m_Create=NULL;
- m_Consumer=NULL;
- product=100;
- m_MutexCreater=CreateMutex(0,0,0);
- m_MutexConsumer=CreateMutex(0,1,0);
- nCount=0;
-
- }
-
- CreaterConsumer::~CreaterConsumer()
- {
-
- }
- bool CreaterConsumer::CreateThreadPool()
- {
- //创建十个线程到线程列表中去
- for(int i=0;i<10;i++)
- {
- m_Create=CreateThread(0,0,&CreateThreadProc,this,0,0);
- if(m_Create)
- {
- m_myCreaterlist.push_back(m_Create);
- }
- }
-
-
- }
-
- bool CreaterConsumer::ConsumerThreadPool()
- {
- //创建十个线程到线程列表中去
- for(int i=0;i<10;i++)
- {
- m_Consumer=CreateThread(0,0,&CreateThreadProc,this,0,0);
- if(m_Consumer)
- {
- m_myConsumerlist.push_back(m_Consumer);
- }
- }
- }
-
- DWORD WINAPI CreaterConsumer::CreateThreadProc(LPVOID lpvoid)
- {
- CreaterConsumer* pthis=(CreaterConsumer*)lpvoid;
- while(1)
- {
- if(pthis->nCount<100)
- {
- WaitForSingleObject(pthis->m_MutexCreater,INFINITE);
- if(pthis->nCount>=100)
- {
- ReleaseMutex( pthis->m_MutexConsumer);
- continue;
- }
- //pthis->product++;
- InterlockedIncrement(&pthis->product);
- InterlockedIncrement(&pthis->nCount);
- cout<
nCount< - ReleaseMutex(pthis->m_MutexConsumer);
- }
-
- }
-
- }
-
- DWORD WINAPI CreaterConsumer::ConsumerThreadProc(LPVOID lpvoid)
- {
- CreaterConsumer* pthis=(CreaterConsumer*)lpvoid;
- while(1)
- {
- if(pthis->nCount<100)
- {
- WaitForSingleObject(pthis->m_MutexConsumer,INFINITE);
- if(pthis->nCount>=100)
- {
- ReleaseMutex( pthis->m_MutexCreater);
- continue;
- }
- //pthis->product--;
- InterlockedDecrement(&pthis->product);
- ReleaseMutex(pthis->m_MutexCreater);
- }
-
-
-
- }
-
-
-
- }
-
-
- void CreaterConsumer::DeleteCreaterThreadPool()
- {
- auto ite= m_myCreaterlist.begin();
- while(ite!=m_myCreaterlist.end())
- {
- delete *ite;
- ite++;
- }
- m_myCreaterlist.clear();
-
- if(m_Create)
- {
- CloseHandle(m_Create);
- m_Create=NULL;
- }
- if(m_MutexCreater)
- {
- CloseHandle(m_MutexCreater);
- m_MutexCreater=NULL;
- }
- }
-
- void CreaterConsumer::DeleteConsumerThreadPool()
- {
- auto ite= m_myConsumerlist.begin();
- while(ite!=m_myConsumerlist.end())
- {
- delete *ite;
- ite++;
- }
-
- if(m_Consumer)
- {
- CloseHandle(m_Consumer);
- m_Consumer=NULL;
- }
- if(m_MutexConsumer)
- {
- CloseHandle(m_MutexConsumer);
- m_MutexConsumer=NULL;
- }
-
- }
执行结果

交互次数为100
-
相关阅读:
就以下数据怎么写代码弄成可视化数据,
【编程之路】面试必刷TOP101:链表(11-16,Python实现)
ASEMI新能源快恢复桥EGBJ5006/HGBJ5006
[halcon案例2] 足球场的提取和射影变换
MacBook 往服务器上传、下载文件的几种操作
基于Java+SpringCloud+Mybaties-plus+Vue+elememt 智能停车场管理系统 的设计与实现
GO语言之Goroutine和channel
Web服务器与Http协议
Java基础
JDK中的SPI 与 Dubbo中的SPI
-
原文地址:https://blog.csdn.net/van9527/article/details/126224488