1. 事件

HANDLE m_hEvent; //定义事件的句柄

m_hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);//创建一个事件,当作多线程的时候用到

ResetEvent(m_hEvent);//重置一个事件,重新使事件处于激活状态,使事件无信号

SetEvent( m_hEvent);//使事件有信号

WaitForSingleObject(m_hEvent, 0);当事件有信号时返回值为WAIT_OBJECT_0

总结:CreateEvent的用法

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR lpName // object name
);
该函数创建一个Event同步对象,并返回该对象的Handle

lpEventAttributes 一般为NULL
bManualReset 创建的Event是自动复位还是人工复位, 如果true, 人工复位, 一旦该Event被设置为有信号,则它一直会等到ResetEvent()API被调用时才会恢复无信号. 如果为false, Event被设置为有信号, 则当有一个wait到它的Thread时, 该Event就会自动复位,变成无信号.
bInitialState 初始状态,true,有信号,false无信号
lpName Event对象名

一个Event被创建以后, 可以用OpenEvent() API来获得它的Handle, 用CloseHandle()来关闭它, 用SetEvent()或PulseEvent()来设置它使其有信号,ResetEvent()来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号.

PulseEvent()是一个比较有意思的使用方法,正如这个API的名字,它使一个Event对象的状态发生一次脉冲变化,从无信号变成有信号再变成无信号,而整个操作是原子的. 对自动复位的Event对象,它仅释放第一个等到该事件的thread(如果有),而对于人工复位的Event对象,它释放所有等待的thread.

WaitForSingleObject的用法

DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
参数hHandle是一个事件的句柄,第二个参数dwMilliseconds是时间间隔。如果时间是有信号状态返回WAIT_OBJECT_0,如果时间超过dwMilliseconds值但时间事件还是无信号状态则返回WAIT_TIMEOUT。

hHandle可以是下列对象的句柄:Change notification 、Console input 、Event Job 、

Memory resource notification 、Mutex 、Process 、

Semaphore 、Thread 、Waitable timer

WaitForSingleObject函数用来检测hHandle事件的信号状态,当函数的执行时间超过dwMilliseconds就返回,但如果参数dwMilliseconds为INFINITE时函数将直到相应时间事件变成有信号状态才返回,否则就一直等待下去,直到WaitForSingleObject有返回值才执行后面的代码。

WaitForMultipleObjects的用法

DWORD WaitForMultipleObjects(
DWORD nCount, // 等待的对象数量
CONST HANDLE *lpHandles, // 对象句柄数组指针
BOOL fWaitAll, // 等待方式,为TRUE表示等待全部对象都变为有信号状态才返回,为FALSE表示任何一

//个对象变为有信号状态则返回
DWORD dwMilliseconds // 超时设置,以ms为单位,如果为INFINITE表示无限期的等待
);

返回值意义:
WAIT_OBJECT_0 到 (WAIT_OBJECT_0 + nCount – 1):当fWaitAll为TRUE时,表示所有对象变为有信号状态;当fWaitAll为FALSE时,使用返回值减去WAIT_OBJECT_0得到变为有信号状态的对象在数组中的下标。
WAIT_ABANDONED_0 到 (WAIT_ABANDONED_0 + nCount – 1):当fWaitAll为TRUE时,表示所有对象变为有信号状态;当fWaitAll为FALSE时,表示对象中有一个对象为互斥量,该互斥量因为被关闭而成为有信号状态,使用返回值减去WAIT_OBJECT_0得到变为有信号状态的对象在数组中的下标。
WAIT_TIMEOUT:表示超过规定时间。

2. 线程

private://在类中定义私有变量
HANDLE m_hHandle;
unsigned int m_uThrID;

//在类外定义全局函数
void ThreadFunc(void *Param);//全局函数

//创建线程,开始调用线程函数
m_hHandle=(HANDLE)_beginthreadex(NULL,0,(unsigned (__stdcall *)(void *))&ThreadFunc,
this,0,&m_uThrID);

//定义线程函数
void ThreadFunc(void *Param)
{
CLineTstDlg *fg_thread= (CLineTstDlg *)Param;//CLineTstDlg 为类名

CString path = fg_thread->path0;//path0为类中的变量

while(WAIT_OBJECT_0 != WaitForSingleObject(fg_thread->m_hEvent, 0))//利用事件控制线程里的循环
{//添加要处理的程序
}
ResetEvent( fg_thread->m_hEvent);//当事件产生时,跳出循环。再使事件变为无信号状态
return;
}

其他的线程函数还有:CreateThread、_beginthread、_beginthreadex、AfxBeginThread

CreateThread是Windows的API函数;而_beginthread和_beginthreadex则是CRT库函数,查看这两个CRT函数的代码可以得知其实它们内部是调用的CreateThread;AfxBeginThread为MFC中的函数。

3. 线程与事件的结合

例1:

#include <windows.h>
#include <iostream.h>
DWORD WINAPI ThreadFunc(HANDLE Thread)
{
int i;
for(i=0;i<10;i++)
{
cout<<“A new thread has created!”<<endl;
}
return 0;
}

int main(int argc,char* argv[])
{
HANDLE Thread;
DWORD dwThreadId;
Thread=::CreateThread(NULL,0,ThreadFunc,NULL,0,&dwThreadId);
cout<<“The new thread ID is :”<<dwThreadId<<endl;
::WaitForSingleObject(Thread,INFINITE);
::CloseHandle(Thread);
return 0;
}

例2:

CEvent g_event; //创建一个全局Event对象g_event

在程序中可以通过调用CEvent::SetEvent设置事件为有信号状态。

下面是一个线程函数MyThreadPro()

UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

WaitForSingleObject(g_event,INFINITE);

for(;;) { …………. }

return 0;

}

在这个线程函数中只有设置g_event为有信号状态时才执行下面的for循环,因为g_event是全局变量,所以我们可以在别的线程中通过g_event. SetEvent控制这个线程。

还有一种用法就是我们可以通过WaitForSingleObject函数来间隔的执行一个线程函数的函数体

UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

while(WaitForSingleObject(g_event,MT_INTERVAL) != WAIT_OBJECT_0) { ……………… }

return 0;

}

在这个线程函数中可以可以通过设置MT_INTERVAL来控制这个线程的函数体多久执行一次,当事件为无信号状态时函数体隔MT_INTERVAL执行一次,当设置事件为有信号状态时,线程就执行完毕了。

版权声明:本文为Sniper-quay原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Sniper-quay/archive/2012/03/03/2378375.html