多執行緒之生產者消費者
看了別人寫的多執行緒例子,自己也寫了一個,貼上了防止以後忘記
此例子有2個生產者,4個消費者,4個緩衝區,共生產12件商品
#include "stdafx.h"
#include <stdio.h>
#include <process.h>
#include <windows.h>
HANDLE g_hEventBufferFull,g_hEventBufferEmpty;
CRITICAL_SECTION g_cs;
const int Product_Num=12;//12件商品
const int Buffer_Size=4;//4個緩衝區
int Buffer[Buffer_Size];
int j=0;//生產者正在用的緩衝區
int k=0;//消費者正在用的緩衝區
int i=1;//已生成商品數量,同時代表每個商品的內容
bool gBuffer=false;
unsigned int __stdcall ProductFun(PVOID pM)
{
while(i<=Product_Num)
{
WaitForSingleObject(g_hEventBufferFull,INFINITE);
EnterCriticalSection(&g_cs);
if(Product_Num<i)//這裡生產者緩衝區一直會多執行一次到13,大概是
//因為上一個執行緒i++到13.而第二個執行緒已經在迴圈內,所以為13
//g_hEventBufferFull在消費者正常結束下是大於0的,所以出現資料
//為13的情況,所以特加此判斷
{
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hEventBufferEmpty,1,NULL);
break;
}
Buffer[j]=i;
printf("編號為%d的生產者在緩衝區%d中投放資料%d\n",GetCurrentThreadId(),j,Buffer[j]);
j=(j+1)%Buffer_Size;
i++;
Sleep(50);//Sleep是為了給其他的執行緒騰出一些時間,充分體現出亂序的特點。否則CPU的執行速度很快,
//很可能在其他執行緒剛剛開啟,當前執行緒已經執行完了,造成執行緒有序執行的假象。
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hEventBufferEmpty,1,NULL);
}
printf("生產者%d完成任務,執行緒結束執行\n",GetCurrentThreadId());
return 0;
}
unsigned int __stdcall ConsumerFun(PVOID pM)
{
while(true)
{
WaitForSingleObject(g_hEventBufferEmpty,INFINITE);
EnterCriticalSection(&g_cs);
if(true==gBuffer)
{
break;
}
printf(" 編號為%d的Consumer在緩衝區%d中取走資料%d\n",GetCurrentThreadId(),k,Buffer[k]);
if(Buffer[k]==Product_Num)//這裡的本意是為了結束另一個執行緒,不造成死鎖,但造成了消費重複,所以在
//上邊加了一個判斷
{
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hEventBufferEmpty,1,NULL);
gBuffer=true;
break;
}
k=(k+1)%Buffer_Size;
Sleep(50);
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hEventBufferFull,1,NULL);
}
printf(" 編號為%d的消費者收到通知,執行緒結束執行\n", GetCurrentThreadId());
return 0;
}
int main()
{
printf("生產者消費者問題by ShallWe\n");
InitializeCriticalSection(&g_cs);
g_hEventBufferFull=CreateSemaphore(NULL,4,4,NULL);
g_hEventBufferEmpty=CreateSemaphore(NULL,0,4,NULL);
HANDLE Thread[4];
memset(Buffer,0,sizeof(Buffer));
Thread[0]=(HANDLE)_beginthreadex(NULL,0,ProductFun,NULL,0,NULL);
Thread[1]=(HANDLE)_beginthreadex(NULL,0,ProductFun,NULL,0,NULL);
Thread[2]=(HANDLE)_beginthreadex(NULL,0,ConsumerFun,NULL,0,NULL);
Thread[3]=(HANDLE)_beginthreadex(NULL,0,ConsumerFun,NULL,0,NULL);
WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
for (int i = 0; i < 4; i++)
CloseHandle(Thread[i]);
//銷燬訊號量和關鍵段
CloseHandle(g_hEventBufferFull);
CloseHandle(g_hEventBufferEmpty);
DeleteCriticalSection(&g_cs);
system("pause");
return 0;
}
相關文章
- Java多執行緒——生產者消費者示例Java執行緒
- Java多執行緒——生產者和消費者模式Java執行緒模式
- Java多執行緒14:生產者/消費者模型Java執行緒模型
- 多執行緒-生產者消費者之等待喚醒機制執行緒
- java多執行緒:執行緒間通訊——生產者消費者模型Java執行緒模型
- Java 多執行緒學習(執行緒通訊——消費者和生產者)Java執行緒
- Java 多執行緒基礎(十二)生產者與消費者Java執行緒
- Java多執行緒——消費者與生產者的關係Java執行緒
- Python-多執行緒及生產者與消費者Python執行緒
- python中多執行緒消費者生產者問題Python執行緒
- 多執行緒-生產者消費者問題程式碼1執行緒
- 多執行緒下的生產者和消費者-BlockingQueue執行緒BloC
- JAVA執行緒消費者與生產者模型Java執行緒模型
- python多執行緒+生產者和消費者模型+queue使用Python執行緒模型
- 多執行緒併發如何高效實現生產者/消費者?執行緒
- C#多執行緒學習(三) 生產者和消費者C#執行緒
- 用Python多執行緒實現生產者消費者模式Python執行緒模式
- python 多執行緒實現生產者與消費者模型Python執行緒模型
- Java多執行緒-併發協作(生產者消費者模型)Java執行緒模型
- C# 多執行緒學習(3) :生產者和消費者C#執行緒
- Java多執行緒之併發協作生產者消費者設計模式Java執行緒設計模式
- Java 多執行緒(Java.Thread)------ 執行緒協作(生產者消費者模式)Java執行緒thread模式
- 生產者消費者模式--java多執行緒同步方法的應用模式Java執行緒
- 多執行緒 -- 移動檔案(生產者,消費者模式應用)執行緒模式
- java多執行緒之消費生產模型Java執行緒模型
- 多執行緒-生產者消費者之等待喚醒機制程式碼優化執行緒優化
- 使用Python佇列和多執行緒實現生產者消費者Python佇列執行緒
- python執行緒通訊與生產者消費者模式Python執行緒模式
- 多執行緒-生產者消費者問題程式碼2並解決執行緒安全問題執行緒
- 關於Java多執行緒實現生產者和消費者的問題Java執行緒
- 執行緒間的協作(2)——生產者與消費者模式執行緒模式
- java多執行緒總結六:經典生產者消費者問題實現Java執行緒
- java學習回顧---生產者與消費者問題以及多執行緒補充Java執行緒
- Java多執行緒程式設計(同步、死鎖、生產消費者問題)Java執行緒程式設計
- java 執行緒池、多執行緒併發實戰(生產者消費者模型 1 vs 10) 附案例原始碼Java執行緒模型原始碼
- 多執行緒必考的「生產者 - 消費者」模型,看齊姐這篇文章就夠了執行緒模型
- Java多執行緒15:Queue、BlockingQueue以及利用BlockingQueue實現生產者/消費者模型Java執行緒BloC模型
- 生產者消費者模式模式