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 }