码迷,mamicode.com
首页 > 其他好文 > 详细

生产者消费者问题

时间:2015-08-29 15:30:34      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

问题思路:如果缓冲区没有满则可以生产,如果缓冲区没有空则可以消费。假设缓冲区大小为BUF_SIZE,则生产者生产生产了就通知消费者可取数量+1,消费者消费量则可取数量-1;
解决方法:信号量,定义
HANDLE g_SemaphoreProducer;
//初始可用数量BUF_SIZE,因为一开始没有生产
//最大可用数量BUF_SIZE

HANDLE g_SemaphoreCustomer;
//初始可用数量0,因为一开始没有生产
//最大可用数量BUF_SIZE

生产线程:
if(WaitForsingleObject(g_SemaphoreProducer,INIFINITE) == WAIT_OBJECT_0))
{
//进行生产操作
……..
//通知消费者+1
ReleaseSemaphore(g_SemaphoreCustomer,1,NULL);
}

消费线程
if(WaitForsingleObject(g_SemaphoreCustomer,INIFINITE) == WAIT_OBJECT_0))
{
//进行消费操作
……..
//通知生产者+1
ReleaseSemaphore(g_SemaphoreProducer,1,NULL);
}

//此时消费生产者完成
///下面给出一个生产者一个消费者代码
// MultiThread.cpp : 定义控制台应用程序的入口点。
//

// MultiThread.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;

const int MAX_SIZE = 10;///> 最大产品数量
const int BUF_SIZE = 4;///> 缓冲区大小
const int PROCEDURE_SIZE = 1;///> 生产者数量
const int CUSTOM_SIZE = 1;///> 消费者数量

HANDLE g_hProcedure = INVALID_HANDLE_VALUE;
HANDLE g_hCustomer = INVALID_HANDLE_VALUE;
int g_Putindex = 0;
int g_GetIndex = 0;
CRITICAL_SECTION g_cs;
int g_buffer[BUF_SIZE] = {0};

BOOL SetConsoleColor(WORD wAttributes)  
{  
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  
    if (hConsole == INVALID_HANDLE_VALUE)  
        return FALSE;  

    return SetConsoleTextAttribute(hConsole, wAttributes);  
}  

void PutProduct(int nVal)
{
    EnterCriticalSection(&g_cs);
    g_buffer[g_Putindex%BUF_SIZE] = nVal;
    SetConsoleColor(FOREGROUND_RED);
    cout<<"放入产品"<<nVal<<"  "<<"index"<<g_Putindex%BUF_SIZE        <<"threadID"<<"  "<<GetCurrentThreadId()<<endl;
    ++g_Putindex;
    LeaveCriticalSection(&g_cs);
}

int GetProduct()
{
    int nVal = 0;
    EnterCriticalSection(&g_cs);
    nVal = g_buffer[g_GetIndex%BUF_SIZE];
    SetConsoleColor(FOREGROUND_GREEN);
    cout<<"取出产品"<<nVal<<"  "<<"index"<<g_GetIndex%BUF_SIZE        <<"threadID"<<"  "<<GetCurrentThreadId()<<endl;
    ++g_GetIndex;
    LeaveCriticalSection(&g_cs);
    return nVal;
}

unsigned int __stdcall Procedure(void* lParam)
{
    for (int i = 0;i < MAX_SIZE;++i)
    {
        if(WaitForSingleObject(g_hProcedure,INFINITE) == WAIT_OBJECT_0)
        {
            PutProduct(i+1);
            ReleaseSemaphore(g_hCustomer,1,NULL);
        }
    }
    return 0;
}

unsigned int __stdcall Customer(void * lParam)
{
    while(TRUE)
    {
        if(WaitForSingleObject(g_hCustomer,INFINITE) == WAIT_OBJECT_0)
        {
            int i = GetProduct();
            if(g_GetIndex == MAX_SIZE)
            {
                break;
            }
            ReleaseSemaphore(g_hProcedure,1,NULL);
        }
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE h[PROCEDURE_SIZE+CUSTOM_SIZE] ={0};
    InitializeCriticalSection(&g_cs);
    g_hProcedure = CreateSemaphore(NULL,BUF_SIZE,BUF_SIZE,NULL);
    g_hCustomer = CreateSemaphore(NULL,0,BUF_SIZE,NULL);
    for (int i = 0;i < PROCEDURE_SIZE;++i)
    {
        h[i] = (HANDLE)_beginthreadex(NULL,0,Procedure,NULL,0,NULL);
    }

    for (int i = PROCEDURE_SIZE;i < PROCEDURE_SIZE+CUSTOM_SIZE;++i)
    {
        h[i] = (HANDLE)_beginthreadex(NULL,0,Customer,NULL,0,NULL);
    }

    WaitForMultipleObjects(PROCEDURE_SIZE+CUSTOM_SIZE,h,TRUE,INFINITE);

    for (int i = 0;i < PROCEDURE_SIZE+CUSTOM_SIZE;++i)
    {
        CloseHandle(h[i]);
    }
    DeleteCriticalSection(&g_cs);
    CloseHandle(g_hCustomer);
    CloseHandle(g_hProcedure);
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

生产者消费者问题

标签:

原文地址:http://blog.csdn.net/cair2/article/details/48086897

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!