在消费者模型里面,有两个主意点:
1、对于当前消费次数的修改访问需要线程互斥,所以用关键段(也可以是互斥量)进行互斥。
2、需要两个信号量(当然也可以是事件),一个表示缓冲区为空,一个表示缓冲区不为空,用于进程间的同步。
还有一点:注意主线程的结束会导致子线程的结束!!!这里一开始一直没搞清楚,后来才发现在将主线程暂停!
#include<stdio.h> #include<process.h> #include<windows.h> volatile long g_nLoginCount; const int THREAD_NUM = 10; volatile long g_num; CRITICAL_SECTION g_thread; HANDLE g_Semaphore_full,g_Semaphore_empty; //信号量 int num=10; unsigned int __stdcall producer(void *pPM){ int i; for(i=0;i<10;i++){ WaitForSingleObject(g_Semaphore_empty,INFINITE); EnterCriticalSection(&g_thread);//对于g_num因为是共享的数据,需要互斥访问,在写入的时候不能读取 g_num++; printf("生产者NUM : %d\n",g_num); LeaveCriticalSection(&g_thread); ReleaseSemaphore(g_Semaphore_full,1,NULL);//信号量++ } return 0; } unsigned int __stdcall customer(void *pPM){ int ok=1; while(1){ WaitForSingleObject(g_Semaphore_full,INFINITE); EnterCriticalSection(&g_thread);//对于g_num因为是共享的数据,需要互斥访问,在读取的时候不能被访问 printf(" 消费者NUM : %d\n",g_num); LeaveCriticalSection(&g_thread); ReleaseSemaphore(g_Semaphore_empty,1,NULL);//信号量++ if(g_num == 9)ok=0; } return 0; } int main(){ InitializeCriticalSection(&g_thread); g_Semaphore_full = CreateSemaphore(NULL,0,1,NULL);//当前0个资源,最大允许1个同时访 g_Semaphore_empty = CreateSemaphore(NULL,0,1,NULL);//当前0个资源,最大允许1个同时访 HANDLE handle[10]; ReleaseSemaphore(g_Semaphore_empty,1,NULL);//信号量++ handle[0] = (HANDLE)_beginthreadex(NULL,0,producer,NULL,0,NULL); handle[1] = (HANDLE)_beginthreadex(NULL,0,customer,NULL,0,NULL); WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE); getchar(); //一定要在这里设置使主线程停止,否则执行到后面的话,子线程就被关闭了 CloseHandle(handle[0]); CloseHandle(handle[1] ); CloseHandle(g_Semaphore_full); CloseHandle(g_Semaphore_empty); DeleteCriticalSection(&g_thread); return 0; }
后面还有坑,继续!!!