事件对象Event的使用

Posted 牧秦丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件对象Event的使用相关的知识,希望对你有一定的参考价值。

  最近使用到Event,做一下总结。


1、对象的创建:

创建了一个匿名的初始状态为“无信号”状态的Event

HANDLE _hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);


2、信号状态切换:

::SetEvent(_hEvent);        // 设置为有信号状态.
::ResetEvent(_hEvent);      // 设置为无信号状态.


3、信号状态查询:

DWORD dwRet = 0;
int time_ms = 100;

dwRet = ::WaitForSingleObject(_hEvent, INFINITE);

dwRet = ::WaitForSingleObject(_hEvent, 0);

dwRet = ::WaitForSingleObject(_hEvent, time_ms);

可以使用::WaitForSingleObject来查询信号状态。当第二个参数为INFINITE时,将一直等待,直到Event变为有状态。当第二个参数为0时,只是即时查询Event的状态并立即返回。当第二个参数为其他时间时,除非超时或者Event变为有状态才返回。


dwRetWAIT_OBJECT_0时,表示信号变为有状态。若dwRetWAIT_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;
;

因为我们在初始创建Event时将信号状态设为FALSE,此后一直没有变化,所以在_Thread_Proc线程函数中WaitForSingleObject一直在等待1000ms后返回WAIT_TIMEOUT,使得文件的保存操作得以调用。


当程序退出时,CConfigFileMgr对象需要析构,则调用SetEvent将信号设置为有状态,然后紧接着让m_hThread对应的线程进入等待,这时_Thread_Proc又检测到m_hEvent有信号,返回WAIT_OBJECT_0。使得死循环跳出,然后用_endthreadex结束线程。


最终关闭释放所有HANDLE,整个程序结束。可以看出,_Thread_Proc函数实际上起到了一个定时器的效果。






以上是关于事件对象Event的使用的主要内容,如果未能解决你的问题,请参考以下文章

event——事件对象详解

jacascript 事件对象event

IE 的事件对象(event)

event事件对象和clientX,clientY

vue中如何使用event对象

JavaScript——event事件详解