生产者消费者练习

抄自:http://blog.csdn.net/morewindows/article/details/7577591

1. 单生产者,单消费者,单缓冲区

运行结果:

代码:

// Card.cpp : 定义控制台应用程序的入口点。
//
//1个生产者, 1个消费者, 1个缓冲区
//
#include "stdafx.h"
#include <windows.h>
#include <process.h>

//生产产品的个数
const int PRODUCE_NUMBER = 10;
// 两个事件, 前面表示缓冲区空, 后面表示缓冲区满,用于同步
HANDLE g_hEventBufferEmpty, g_hEventBufferFull;
// 临界区域, 用来实现互斥访问
CRITICAL_SECTION g_cs;

//产品
int g_buffer;

//设置控制台字体颜色
BOOL SetConsoleColor(WORD wAttributes)
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hConsole == INVALID_HANDLE_VALUE)
        return FALSE;
    return SetConsoleTextAttribute(hConsole, wAttributes);
}

//生产者线程函数
unsigned int __stdcall ProducerThreadFun(LPVOID pM)
{
    printf("生产者开始生产!\n");
    for (int i = 0; i < PRODUCE_NUMBER; i++)
    {
        //等待缓冲区为空的信号
        WaitForSingleObject(g_hEventBufferEmpty, INFINITE);

        //互斥访问缓冲区
        EnterCriticalSection(&g_cs);
        g_buffer = i;
        printf("生产者将数据%d放入缓冲区\n", i);
        LeaveCriticalSection(&g_cs);

        //生产后设置缓冲区有数据的信号
        SetEvent(g_hEventBufferFull);
    }
    return 0;
}

//消费者线程函数
unsigned int __stdcall ConsumerThreadFun(LPVOID pM)
{
    printf("消费者开始消费!\n");
    while(true)
    {
        //等待缓冲区中有数据
        WaitForSingleObject(g_hEventBufferFull, INFINITE);

        //互斥访问缓冲区
        EnterCriticalSection(&g_cs);
        //g_buffer = i;
        SetConsoleColor(FOREGROUND_GREEN);
        printf("  消费者消费数据%d\n", g_buffer);
        //设置颜色
        SetConsoleColor(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
        if (g_buffer == PRODUCE_NUMBER-1)
            break;
        LeaveCriticalSection(&g_cs);

        //通知缓冲区已为空
        SetEvent(g_hEventBufferEmpty);
        Sleep(500);
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    const int THREADNUM = 2;
    HANDLE hThread[THREADNUM];

    InitializeCriticalSection(&g_cs);

    //创建两个自动复位事件,一个表示缓冲区为空,一个表示缓冲区有数据
    // CreateEvent函数,第二个参数(FALSE)表示是否手动复位,第三个参数(TRUE)表示初始值;
    g_hEventBufferEmpty = CreateEvent(NULL, FALSE, TRUE, NULL);
    g_hEventBufferFull = CreateEvent(NULL, FALSE, FALSE, NULL);

    hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
    hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);

    WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);

    //销毁事件和临界区
    CloseHandle(hThread[0]);
    CloseHandle(hThread[1]);

    CloseHandle(g_hEventBufferFull);
    CloseHandle(g_hEventBufferEmpty);
    DeleteCriticalSection(&g_cs);

    return 0;
}

 

(待续)

posted @ 2015-07-14 12:12  凤舞十天  阅读(286)  评论(0编辑  收藏  举报