zoukankan      html  css  js  c++  java
  • 生产者消费者练习

    抄自: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("生产者开始生产!
    ");
        for (int i = 0; i < PRODUCE_NUMBER; i++)
        {
            //等待缓冲区为空的信号
            WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
    
            //互斥访问缓冲区
            EnterCriticalSection(&g_cs);
            g_buffer = i;
            printf("生产者将数据%d放入缓冲区
    ", i);
            LeaveCriticalSection(&g_cs);
    
            //生产后设置缓冲区有数据的信号
            SetEvent(g_hEventBufferFull);
        }
        return 0;
    }
    
    //消费者线程函数
    unsigned int __stdcall ConsumerThreadFun(LPVOID pM)
    {
        printf("消费者开始消费!
    ");
        while(true)
        {
            //等待缓冲区中有数据
            WaitForSingleObject(g_hEventBufferFull, INFINITE);
    
            //互斥访问缓冲区
            EnterCriticalSection(&g_cs);
            //g_buffer = i;
            SetConsoleColor(FOREGROUND_GREEN);
            printf("  消费者消费数据%d
    ", 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;
    }

    (待续)

  • 相关阅读:
    配置JDK
    360首页(练习)
    表单练习——(简单的注册页面)
    主页
    证明某字母是否最后一个字母
    方法的重载与重写区别
    什么是设计模式
    java 静态方法和实例方法的区别
    什么是静态方法
    手机充电(练习)
  • 原文地址:https://www.cnblogs.com/fwst/p/4645098.html
Copyright © 2011-2022 走看看