习题:假设
有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
-
相关阅读:
Pyhon中利用GM(1,1)和ARIMA模型对卫星DCB值进行预测
极简的MapReduce实现
02|一条MySQL更新语句是如何执行的
@Transactional 的使用
小谈设计模式(6)—依赖倒转原则
安全工具--- rengine安装---资产侦查漏洞扫描
第十四届蓝桥杯模拟赛(第二期)——C语言版
Web请求与响应(SpringBoot)
2023数学建模国赛选题建议及BC题思路
Today‘s web RPC案例
-
原文地址:https://blog.csdn.net/van9527/article/details/126224488