您的位置:首页 > 其它

生产者消费者练习

2015-07-14 12:12 246 查看
抄自:/article/1358215.html

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;
}


(待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: