一. 事件对象
事件对象属于内核对象。包含三个成员:
(1)使用计数
(2)指明该事件是自动重置事件还是人工重置事件的布尔值
(3)指明事件出于已通知状态还是未通知状态的布尔值。
二.人工重置事件和自动重置事件的区别
当人工重置事件对象得到通知时,等待该事件对象的所有线程均变为可调度线程;当一个自动重置的事件对象得到通知时,等待该事件对象的线程中只有一个线程变为可调度线程,同时操作系统会将该事件对象设置为无信号状态,这样,当对所保护的代码执行完成之后,需要调用SetEvent函数将该事件对象设置为有信号状态。而人工重置的事件对象,在一个线程得到该事件对象之后,操作系统并不会将该事件对象设置为无信号状态,除非显示地调用ResetEvent函数将其设置为无信号状态,否则该对象会一直是有信号状态。
三.代码
- #include <windows.h>
- #include <iostream.h>
- //线程入口函数声明
- DWORD WINAPI Fun1Proc(
- LPVOID lpParameter // thread data
- );
- DWORD WINAPI Fun2Proc(
- LPVOID lpParameter // thread data
- );
- int tickets = 100; //票数
- HANDLE g_hEvent; //事件对象句柄
- void main()
- {
- //线程句柄
- HANDLE hThread1;
- HANDLE hThread2;
- //创建人工重置事件内核对象
- g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- //设置事件对象为有信号状态
- SetEvent(g_hEvent);
- //创建线程
- hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
- hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
- //关闭线程句柄,因为主线程不需要再对线程操作
- CloseHandle(hThread1);
- CloseHandle(hThread2);
- //让主线程休眠4秒
- Sleep(4000);
- //关闭事件对象句柄
- CloseHandle(g_hEvent);
- }
- //线程1的入口函数
- DWORD WINAPI Fun1Proc(LPVOID lpParameter)
- {
- while(TRUE)
- {
- //获取事件对象
- WaitForSingleObject(g_hEvent, INFINITE);
- if( tickets>0)
- {
- Sleep(1);
- cout<<"thread1 sell ticket: "<<tickets--<<endl;
- SetEvent(g_hEvent);
- }
- else
- {
- SetEvent(g_hEvent);
- break;
- }
- }
- return 0;
- }
- //线程2的入口函数
- DWORD WINAPI Fun2Proc(LPVOID lpParameter)
- {
- while(TRUE)
- {
- //获取事件对象
- WaitForSingleObject(g_hEvent, INFINITE);
- if( tickets>0)
- {
- Sleep(1);
- cout<<"thread2 sell ticket: "<<tickets--<<endl;
- SetEvent(g_hEvent);
- }
- else
- {
- SetEvent(g_hEvent);
- break;
- }
- }
- return 0;
- }