转自:http://blog.csdn.net/xhysherry/article/details/6253761
VC声明DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
VB声明Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
参数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毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。
返回值:
WAIT_ABANDONED 0x00000080:当hHandle为mutex时,如果拥有mutex的线程在结束时没有释放核心对象会引发此返回值。
WAIT_OBJECT_0 0x00000000 :核心对象已被激活
WAIT_TIMEOUT 0x00000102:等待超时
WAIT_FAILED 0xFFFFFFFF :出现错误,可通过GetLastError得到错误代码
在这里举个例子:
先创建一个全局Event对象g_event:
CEvent 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执行一次,当设置事件为有信号状态时,线程就执行完毕了。
学习:
使用等待函数即可以保证线程的同步,又可以提高程序的运行效率。最常用的等待函数是WaitForSingleObject,该函数的声明为:
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
参数hHandle是同步对象的句柄。参数dwMilliseconds是以毫秒为单位的超时间隔,如果该参数为0,那么函数就测试同步对象的状态并立即返回,如果该参数为INFINITE,则超时间隔是无限的。
WaitForSingleObject的返回值
返回值 含义
WAIT_FAILED 函数失败
WAIT_OBJECT_0 指定的同步对象处于有信号的状态
WAIT_ABANDONED 拥有一个mutex的线程已经中断了,但未释放该MUTEX
WAIT_TIMEOUT 超时返回,并且同步对象无信号
hConsoleInput是一个Waitable句柄,意味着你可以使用WaitForSingleObject来检测是否有输入Present,在调用ReadConsoleInput之后,应该调用FlushConsoleInputBuffer刷新Input缓冲区
例子...
#i nclude
#i nclude
void main(){
HANDLE keyboard;
DWORD Read;
INPUT_RECORD Event;
keyboard = GetStdHandle(STD_INPUT_HANDLE);
while(true){
if(WaitForSingleObject(keyboard,0) == WAIT_OBJECT_0){
ReadConsoleInput(keyboard, &Event, 1, &Read);
if(Event.EventType == KEY_EVENT){
if(Event.Event.KeyEvent.bKeyDown){
if(Event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE){
break;
}
else{
cout<
}
}
FlushConsoleInputBuffer(keyboard);
}
cout<<"Are you OK???"<
}