1 //生产者消费者问题 2 //使用事件和互斥量实现 3 //缓冲区只能放一个产品 4 5 //有人可能疑问,为什么不能用两个互斥量来实现同步, 6 //像使用两个事件一样。因为互斥量具有线程所有的概念, 7 //等待函数执行后,互斥量会保存当前线程id,表示这个互斥量属于这个线程。 8 //当你在另一个线程Release这个互斥量时,因为互斥量保存的线程ID与当前 9 //线程ID不一致,操作将返回FALSE。 10 #include <iostream> 11 #include <Windows.h> 12 13 //互斥量 14 HANDLE g_hMutex; 15 //事件 16 HANDLE g_hEventBufferEmpty, g_hEventBufferFull; 17 //缓冲区,只能放一个产品 18 int g_Buffer; 19 20 DWORD WINAPI ProducterThreadFunc(PVOID pM) 21 { 22 int i; 23 for(i = 1; i <= 10; i++) 24 { 25 WaitForSingleObject(g_hEventBufferEmpty, INFINITE); 26 //等待互斥量被释放(触发) 27 WaitForSingleObject(g_hMutex, INFINITE); 28 29 g_Buffer = i; 30 std::cout<<"生产者放入产品:"<<i<<std::endl; 31 //释放互斥量 32 ReleaseMutex(g_hMutex); 33 34 SetEvent(g_hEventBufferFull); 35 } 36 return 0; 37 } 38 DWORD WINAPI ConsumerFunc(PVOID pM) 39 { 40 int i; 41 for(i = 1; i <= 10; i++) 42 { 43 WaitForSingleObject(g_hEventBufferFull, INFINITE); 44 //等待互斥量触发 45 WaitForSingleObject(g_hMutex,INFINITE); 46 47 std::cout<<" 消费者拿出产品:"<<g_Buffer<<std::endl; 48 49 50 //释放互斥量 51 ReleaseMutex(g_hMutex); 52 SetEvent(g_hEventBufferEmpty); 53 } 54 return 0; 55 } 56 int main() 57 { 58 //设置互斥量为触发状态(释放),第2个参数FALSE 59 g_hMutex = CreateMutex(NULL, FALSE, NULL); 60 61 62 //事件 63 //开始设置缓冲区为空的事件触发,第3个参数 64 g_hEventBufferEmpty = CreateEvent(NULL, FALSE, TRUE, NULL); 65 //设置缓冲区满的事件未触发 66 g_hEventBufferFull = CreateEvent(NULL, FALSE, FALSE, NULL); 67 68 //线程 69 HANDLE hThread[2]; 70 hThread[0] = CreateThread(NULL, 0, ProducterThreadFunc, NULL, 0, NULL); 71 72 hThread[1] = CreateThread(NULL, 0, ConsumerFunc, NULL, 0, NULL); 73 WaitForMultipleObjects(2, hThread, TRUE, INFINITE); 74 75 std::cout<<std::endl<<"执行完成。 "<<std::endl; 76 CloseHandle(hThread[0]); 77 CloseHandle(hThread[1]); 78 79 CloseHandle(g_hEventBufferEmpty); 80 CloseHandle(g_hEventBufferFull); 81 CloseHandle(g_hMutex); 82 return 0; 83 }