WaitForSingleObject和 WaitForMultipleObjects

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有返回值才执行后面的代码。此外,当dwMilliseconds设置为特殊值0时,测试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执行一次,当设置事件为有信号状态时,线程就执行完毕了。

 

 

DWORD WaitForMultipleObjects(DWORD dwCount,

                 CONST HANDLE * phObjects,

                 BOOL fWaitAll,

                 DWORD dwMillseconds);

dwCount 参数用于指明函数要查看的内核对象的数量。这个值必须在1与MAXIMUM_WAIT_OBJECTS(windows头文件中定义为64之间)。

phObjects参数是指向内核对象句柄的数组的指针。

可以以两种不同的方式来使用WaitForMultipleObjects函数

1 让线程进入等待状态,直到指定内核对象中任何一个变为已通知状态

2 让线程进入等待状态,直到所有指定的内核对象都变为已通知状态。

fWaitAll参数告诉该函数使用何种方式。如果为该参数传递TRUE,那么在所有对象变为已通知状态之前,该函数不允许调用线程运行。

dwMillseconds参数的作用与它在WaitForSingObject中的作用完全相同。如果等待规定的时间到了,那么该函数无论如何都会返回。同样,通常为该参数传递INFINITE,但是在编写代码时候应该小心,以避免出现死锁情况。

WaitForMultipleObjects函数的返回值告诉调用线程,为什么它会被重新调度。可能的返回值是WAIT_FAILED和WAIT_TIMEOUT,这两个值的作用是很清楚的。如果fWaitALL参数传递TRUE,同时所有对象均变为已通知状态,那么返回值是WAIT_OBJECT_0。如果fWaitAll传递FALSE,那么一旦任何一个对象变为已通知状态,该函数变返回。这种情况下,如果想要知道哪个对象变为已通知状态。返回值是WAIT_OBJECT_0与(WAIT_OBJECT_0+dwCount-1)之间的一个值。也就是说,如果返回值不是WAIT_TIMEOUT,也不是WAIT_FAILED,那么应该从返回值中减去WAIT_OBJECT_0。产生的数字是作用第二个参数传递给WaitForMultipleObjects的句柄数组中的索引。该索引说明哪个对象变为已通知状态。

示例:

HANDLE h[3]

h[0]=hProcess1;

h[1]=hProcess2;

h[3]=hProcess3;

DWORD dw=WaitForMultipleObjects(3,h,FALSE,5000);

switch(dw)

{

 case WAIT_FAILED:

 //bad call to function(invalid handle?)

break;

case WAIT_TIMEOUT:

//none of the objects became signaled within 5000 millisecond

break;

case WAIT_OBJECT_0 +1:

//the process identified by h[1](hProcess2) terminated.

break;

case WAIT_OBJECT_0+2:

//the process identified by h[2](hProcess3) terminated.

break;

}

如果为fWaitAll参数传递FALSE,WaitForMultipleObjects就从索引0开始向上对句柄数组进行扫描,同时已通知的第一个对象终止等待状态。这可能产生一些你不希望有的结果。例如,通过将3个进程句柄传递给该函数,你的线程就会等待3个子进程终止运行。如果数组中索引为0的进程终止运行,WaitForMultipleObjects就会返回。这时该线程就可以做它需要的任何事情,然后循环反复,等待另一个进程终止运行。如果该线程传递相同的三个句柄,该函数立即再次返回WAIT_OBJECT_0,除非已经收到通知的句柄,否则代码就无法正确地运行。

总结:两者区别为,WaitForSingleObject 等待单一句柄对象, WaitForMultipleObjects 可等待多个句柄对象,由其第一个参数指定的句柄数组.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值