操作系统 生产者消费者 练习

习题:假设

有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 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值