最近使用到Event,做一下总结。
1、对象的创建:
创建了一个匿名的初始状态为“无信号”状态的Event。
HANDLE _hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
2、信号状态切换:
::SetEvent(_hEvent); // 设置为有信号状态. ::ResetEvent(_hEvent); // 设置为无信号状态.
DWORD dwRet = 0; int time_ms = 100; dwRet = ::WaitForSingleObject(_hEvent, INFINITE); dwRet = ::WaitForSingleObject(_hEvent, 0); dwRet = ::WaitForSingleObject(_hEvent, time_ms);
当dwRet为WAIT_OBJECT_0时,表示信号变为有状态。若dwRet为WAIT_TIMEOUT,表示超时。
4、使用示例
我们用一个使用示例来看看Event的用法。比如我们有三块缓存或者文件,需要在整个程序运行过程中每隔1000ms保存一次。如下:
class CMyRawFile { public: void Save(); // ... }; class CConfigFileMgr { public: CConfigFileMgr() : m_hEvent(NULL), m_hThread(NULL) { unsigned int id = 0; m_hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); m_hThread = (HANDLE)_beginthreadex(NULL, 0, _Thread_Proc, (void*)this, 0, &id); if (m_hThread) { ::WaitForSingleObject(m_hThread, 10); } } ~CConfigFileMgr() { if (m_hThread) { if (m_hEvent) { ::SetEvent(m_hEvent); } ::WaitForSingleObject(m_hThread, INFINITE); ::CloseHandle(m_hThread); m_hThread = NULL; } if (m_hEvent) { ::CloseHandle(m_hEvent); m_hEvent = NULL; } } static unsinged __stdcall _Thread_Proc(void* pParam) { CConfigFileMgr* pThis = (CConfigFileMgr*)pParam; if (!pThis) { return 0; } while (true) { DWORD dwRet = ::WaitForSingleObject(m_hEvent, 1000); if (dwRet == WAIT_OBJECT_0) { break; } else if (dwRet == WAIT_TIMEOUT) { pThis->m_sysConfig.Save(); pThis->m_usrConfig.Save(); pThis->m_cache.Save(); } } pThis->m_sysConfig.Save(); pThis->m_usrConfig.Save(); pThis->m_cache.Save(); _endthreadex(0); return 0; } private: HANDLE m_hEvent; HANDLE m_hThread; CMyRawFile m_sysConfig; CMyRawFile m_usrConfig; CMyRawFile m_cache; };
当程序退出时,CConfigFileMgr对象需要析构,则调用SetEvent将信号设置为有状态,然后紧接着让m_hThread对应的线程进入等待,这时_Thread_Proc又检测到m_hEvent有信号,返回WAIT_OBJECT_0。使得死循环跳出,然后用_endthreadex结束线程。
最终关闭释放所有HANDLE,整个程序结束。可以看出,_Thread_Proc函数实际上起到了一个定时器的效果。