多线程-生产者与消费者问题

来源:互联网 发布:死神游戏单机不要网络 编辑:程序博客网 时间:2024/05/29 18:53

参考http://blog.csdn.net/morewindows/article/details/7577591实现的简单例子


一个生产者、一个消费者、一个缓冲区

#include <stdio.h>#include <process.h>#include <windows.h>#include <iostream>using namespace std;const int PRODUCE_NUMBER = 50;int g_iHole;HANDLE g_hEventHoleEmpty;// 坑空事件 HANDLE g_hEventHoleFull;// 坑满事件 unsigned int __stdcall uiProduceTread(void* p){int l_iShouldProduceNum = PRODUCE_NUMBER;while(l_iShouldProduceNum--){WaitForSingleObject(g_hEventHoleEmpty, INFINITE);g_iHole = PRODUCE_NUMBER-l_iShouldProduceNum;printf("putin %d\n", g_iHole); Sleep(10);SetEvent(g_hEventHoleFull);}return 0;}unsigned int __stdcall uiConsumeTread(void* p){int l_iConsumeCnt = 1;while(l_iConsumeCnt <= PRODUCE_NUMBER){WaitForSingleObject(g_hEventHoleFull, INFINITE);printf("---getout %d\n", g_iHole); l_iConsumeCnt++;SetEvent(g_hEventHoleEmpty);}return 0;}int main(int argc, char* argv[]){g_hEventHoleFull = CreateEvent(NULL, FALSE, FALSE, NULL);  g_hEventHoleEmpty = CreateEvent(NULL, FALSE, TRUE, NULL);   HANDLE handle1 = (HANDLE)_beginthreadex(NULL, 0, &uiProduceTread, NULL, 0, NULL);HANDLE handle2 = (HANDLE)_beginthreadex(NULL, 0, &uiConsumeTread, NULL, 0, NULL);HANDLE l_haHandleArray[2] = {handle1, handle2};cout << handle1 << endl << handle2 << endl << endl;WaitForMultipleObjects(2, l_haHandleArray, TRUE, INFINITE); cout << handle1 << endl << handle2 << endl << endl;CloseHandle(handle1);      CloseHandle(handle2);  CloseHandle(g_hEventHoleFull);      CloseHandle(g_hEventHoleEmpty);  return 0;}




一个生产者、多个消费者、多个缓冲区

#include <iostream>#include <windows.h>using namespace std;const int NUM_OF_PRODUCER = 1;//生产者个数 const int NUM_OF_CONSUMER = 2;//消费者个数 const int NUM_OF_HOLE = 4;//坑个数 const int NUM_OF_PRODUCT= 10;//要生产的产品个数 HANDLE g_hHandles[NUM_OF_PRODUCER+NUM_OF_CONSUMER];//线程句柄数组 HANDLE g_hSemaphoreFull;//表示坑满信号量 HANDLE g_hSemaphoreEmpty;//表示坑空信号量 HANDLE g_hExitEvent;int g_iaHole[NUM_OF_HOLE] = {0};//坑数组 CRITICAL_SECTION g_cs;//关键段void vInitHole(void){int i = 0;for(i=0; i<NUM_OF_HOLE; i++){g_iaHole[i] = -1;}}int iIsHoleEmpty(){int i = 0;for(i=0; i<NUM_OF_HOLE; i++){if(-1 != g_iaHole[i]){return 0;}}return 1;}void vShowHole(){int i = 0;printf("\t\tHOLE:");for(i=0; i<NUM_OF_HOLE; i++){printf("%d\t", g_iaHole[i]);}printf("\n");}int iProduce(DWORD p_dwThreadID, int* p_iSite, int* p_ProductID){int l_iResult = 0;static int l_siHoleSite = 0;EnterCriticalSection(&g_cs);if(-1 != g_iaHole[l_siHoleSite]){l_iResult = 1;}else{*p_iSite = l_siHoleSite;//生产的产品存放的位置 *p_ProductID = *p_ProductID; //生产的产品 g_iaHole[l_siHoleSite] = *p_ProductID;//生产 printf("Thread %d:Produce %d in %d\n", p_dwThreadID, *p_ProductID, l_siHoleSite);l_siHoleSite++;if(l_siHoleSite >= NUM_OF_HOLE){l_siHoleSite = 0;}vShowHole(); printf("\n"); }LeaveCriticalSection(&g_cs);return l_iResult;}int iConsume(DWORD p_dwThreadID, int* p_iSite, int* p_ProductID){int l_iResult = 0;static int l_siHoleSite = 0;EnterCriticalSection(&g_cs);if(-1 == g_iaHole[l_siHoleSite]){l_iResult = 1;}else{*p_iSite = l_siHoleSite;//消费的产品存放的位置 *p_ProductID = g_iaHole[l_siHoleSite];//消费的产品 g_iaHole[l_siHoleSite] = -1;//消费printf("Thread %d:consume %d in %d\n", p_dwThreadID, *p_ProductID, l_siHoleSite);l_siHoleSite++;if(l_siHoleSite >= NUM_OF_HOLE){l_siHoleSite = 0;}vShowHole();printf("\n"); }LeaveCriticalSection(&g_cs);return l_iResult;}unsigned int __stdcall uiProducerThread(void* p){int l_iProduceResult = 0;int l_iProductID = 0;int l_iProduceSite = 0;DWORD l_lThreadID = GetCurrentThreadId();HANDLE l_hProduceHandle[2] = {g_hSemaphoreEmpty, g_hExitEvent};while(l_iProductID < NUM_OF_PRODUCT){DWORD l_dwObj = WaitForMultipleObjects(2, l_hProduceHandle, FALSE, INFINITE);if(WAIT_OBJECT_0 == l_dwObj)//坑空信号量有信号 {l_iProduceResult = iProduce(l_lThreadID, &l_iProduceSite, &l_iProductID);//生产if(0 != l_iProduceResult){printf("Producer Error!\n");SetEvent(g_hExitEvent);}ReleaseSemaphore(g_hSemaphoreFull, 1, NULL); }else if(WAIT_OBJECT_0+1 == l_dwObj)//退出事件 {printf("Producer Exit!\n");break; }else{}l_iProductID++;}SetEvent(g_hExitEvent);return 0;}unsigned int __stdcall uiConsumerThread(void* p){int l_iConsumeResult = 0;int l_iProductID = 0;int l_iProduceSite = 0;DWORD l_lThreadID = GetCurrentThreadId();HANDLE l_hConsumeHandle[2] = {g_hSemaphoreFull, g_hExitEvent};while(l_iProductID < NUM_OF_PRODUCT){DWORD l_dwObj = WaitForMultipleObjects(2, l_hConsumeHandle, FALSE, INFINITE);if(WAIT_OBJECT_0 == l_dwObj) //坑满信号量有信号 {l_iConsumeResult = iConsume(l_lThreadID, &l_iProduceSite, &l_iProductID);//消费if(0 != l_iConsumeResult) {printf("Consumer Error!\n");SetEvent(g_hExitEvent);}ReleaseSemaphore(g_hSemaphoreEmpty, 1, NULL); }else if(WAIT_OBJECT_0+1 == l_dwObj)//退出事件 {if(1 == iIsHoleEmpty()){break;} }else{}}return 0;}int main(){int l_iProducerCnt = 0;int l_iConsumerCnt = 0;int l_iHandleCnt = 0;vInitHole();InitializeCriticalSection(&g_cs);g_hExitEvent= CreateEvent( NULL,// 安全控制,一般直接传入NULL。                              TRUE,// 确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。                              FALSE,// 事件的初始状态,传入TRUE表示已触发。                              NULL);// 事件的名称,传入NULL表示匿名事件。g_hSemaphoreFull = CreateSemaphore(NULL, 0, NUM_OF_HOLE, NULL);//表示坑满信号量 g_hSemaphoreEmpty = CreateSemaphore(NULL, NUM_OF_HOLE, NUM_OF_HOLE, NULL);//表示坑空信号量 for(l_iProducerCnt=0; l_iProducerCnt<NUM_OF_PRODUCER; l_iProducerCnt++){g_hHandles[l_iProducerCnt] = (HANDLE)_beginthreadex(NULL, 0, uiProducerThread, NULL, 0, NULL);//生产者 }for(l_iConsumerCnt=0; l_iConsumerCnt<NUM_OF_CONSUMER; l_iConsumerCnt++){g_hHandles[l_iProducerCnt+l_iConsumerCnt] = (HANDLE)_beginthreadex(NULL, 0, uiConsumerThread, NULL, 0, NULL);//消费者} WaitForMultipleObjects(NUM_OF_PRODUCER+NUM_OF_CONSUMER, g_hHandles, TRUE, INFINITE);DeleteCriticalSection(&g_cs);CloseHandle(g_hExitEvent);CloseHandle(g_hSemaphoreFull);CloseHandle(g_hSemaphoreEmpty);for(l_iHandleCnt=0; l_iHandleCnt<NUM_OF_PRODUCER+NUM_OF_CONSUMER; l_iHandleCnt++){CloseHandle(g_hHandles[l_iHandleCnt]);}return 0;}






0 0
原创粉丝点击