习题:假设
有10个生产者和10个消费者
初始物品100个
生产者一次生产一件物品 消费者一次消费一件物品
生产者每生产一件物品 消费者就消费掉一件
消费者每消费掉一件 生产者就生产一件物品
直到这样交互100次
思想 :10个消费者为一个线程池 10个生产者为一个线程池
消费者任务 物品--;
生产者任务 物品++;
这里有个条件
1.
每次执行 物品--; 或 物品++;时 我们只想让一个生产者或消费者去执行 其他的人等待 所以这里我们用到了互斥量 同一时刻只允许一个线程执行
2.
生产者一次生产一件物品 消费者一次消费一件物品
生产者每生产一件物品 消费者就消费掉一件
这我们可以利用互斥量的信号的获取和释放来实现
当生产者获取到生产者的互斥量信号 它生产一件物品 然后释放掉消费者的互斥量信号
消费者获取到消费者的互斥量信号 它消费一件物品 然后释放掉生产者的互斥量信号
如此往复
完整代码如下
生产者消费者类的声明
#ifndef CREATER_H
#define CREATER_H
#include<windows.h>
#include<list>
#include<queue>
class CreaterConsumer
{
private:
//生产者句柄
HANDLE m_Create;
//消费者句柄
HANDLE m_Consumer;
//生产者线程链表
std::list<HANDLE> m_myCreaterlist;
//消费者线程链表
std::list<HANDLE> 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<iostream>
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<<pthis->nCount<<endl;
//释放消费者信号
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<iostream>
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<<pthis->nCount<<endl;
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