1 #include <stdio.h> 2 #include <process.h> 3 #include <Windows.h> 4 //信號量與關鍵段 5 CRITICAL_SECTION g_cs; 6 HANDLE Empty,Full; 7 8 const int BUFFER_SIZE=10;//10個緩衝池 9 const int numofp=2;//生產者線程數 10 const int numofc=2;//消費者線程數 11 const int numofpr=100;//要生產的產品數 12 int buffer[BUFFER_SIZE]; 13 int pf=0,pe=0; 14 int count=1; 15 int count_c=1; 16 int mp=0; 17 18 //生產者 19 unsigned int __stdcall Producer(PVOID p){ 20 21 while(true){ 22 //等待有空的緩衝區出現 23 WaitForSingleObject(Empty, INFINITE); 24 //互斥的訪問緩衝區 25 EnterCriticalSection(&g_cs); 26 if(count>numofpr){ 27 LeaveCriticalSection(&g_cs); 28 ReleaseSemaphore(Full,1,NULL); 29 break; 30 } 31 buffer[pe]=++mp; 32 //printf("%d,",*((int *)p)); 33 printf("編號爲%d的生產者從第%d個空緩衝池中寫入數據%d\n",*((int *)p),pe,buffer[pe]); 34 pe=(pe+1)%BUFFER_SIZE; 35 count++; 36 LeaveCriticalSection(&g_cs); 37 //通知消費者有新數據了 38 ReleaseSemaphore(Full,1,NULL); 39 } 40 return 0; 41 } 42 //消費者 43 unsigned int __stdcall Consumer(PVOID p){ 44 45 while(true){ 46 WaitForSingleObject(Full,INFINITE); 47 EnterCriticalSection(&g_cs); 48 if(count_c>numofpr){ 49 LeaveCriticalSection(&g_cs); 50 ReleaseSemaphore(Empty,1,NULL); 51 break; 52 } 53 //printf("%d,",*((int *)p)); 54 printf(" 編號爲%d的消費者從第%d個FULL緩衝區中取出數據%d\n",*((int *)p),pf,buffer[pf]); 55 pf=(pf+1)%BUFFER_SIZE; 56 count_c++; 57 LeaveCriticalSection(&g_cs); 58 ReleaseSemaphore(Empty,1,NULL); 59 } 60 return 0; 61 } 62 63 int main(){ 64 printf(" 生產者消費者問題:%d生產者-%d消費者-%d緩衝區-%d個產品\n\n",numofp,numofc,BUFFER_SIZE,numofpr); 65 InitializeCriticalSection(&g_cs);//初始化一個臨界區對象 66 //初始化信號量,一個記錄有產品的緩衝區個數,另外一個記錄空緩衝區個數. 67 Empty=CreateSemaphore(NULL,10,10,NULL); 68 Full=CreateSemaphore(NULL,0,10,NULL); 69 const int THREADNUM=numofc+numofp;//線程數 70 HANDLE hThread[THREADNUM]; 71 //生產者線程 72 int a=1,b=2,c=3,d=4; 73 hThread[0]=(HANDLE)_beginthreadex( 74 NULL,//安全屬性,NULL爲默認安全屬性 75 0,//指定線程堆棧的大小,通常爲0 76 Producer,//指定線程函數的地址 77 &a,//傳遞給線程的參數的指針 78 0,//線程初始狀態,0:當即運行 79 NULL);//用於記錄線程ID的地址 80 81 hThread[1]=(HANDLE)_beginthreadex(NULL,0,Producer,&b,0,NULL); 82 83 hThread[2]=(HANDLE)_beginthreadex(NULL,0,Consumer,&c,0,NULL); 84 85 hThread[3]=(HANDLE)_beginthreadex(NULL,0,Consumer,&d,0,NULL); 86 WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE); 87 for (int i = 0; i < THREADNUM; i++) 88 CloseHandle(hThread[i]); 89 90 //銷燬信號量和關鍵段 91 CloseHandle(Empty); 92 CloseHandle(Full); 93 DeleteCriticalSection(&g_cs); 94 system("pause"); 95 96 return 0; 97 }