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<<"执行完成。\n"<<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 }