WaitForMultipleObjects函数

转载 2011年01月15日 00:48:00
WaitForMultipleObjects函数解释及其用法
2009-04-24 11:29

 

 
函数原型:
DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in array
CONST HANDLE *lpHandles, // object-handle array
BOOL bWaitAll, // wait option
DWORD dwMilliseconds // time-out interval
);

WaitForMultipleObjects函数用于等待多个内核对象,前两个参数分别为要等待的内核对象的个数和句柄数组指针。如果将第三个参数bWaitAll的值设为TRUE,等待的内核对象全部变成受信状态以后此函数才返回。否则,bWaitAll0的话,只要等待的内核对象中有一个变成了受信状态,WaitForMultipleObjects就返回,返回值指明了是哪一个内核对象变成了受信状态。

实例一:

下面的代码说明了函数返回值的作用:

         HANDLE h[2];

         h[0] = hThread1;

         h[1] = hThread2;

         DWORD dw = ::WaitForMultipleObjects(2, h, FALSE, 5000);

         switch(dw)

         {       case WAIT_FAILED:

                            // 调用WaitForMultipleObjects函数失败(句柄无效?)

                            break;

                   case WAIT_TIMEOUT:

                            // 5秒内没有一个内核对象受信

                            break;

                   case WAIT_OBJECT_0 + 0:

                            // 句柄h[0]对应的内核对象受信

                            break;

                   case WAIT_OBJECT_0 + 1:

                            // 句柄h[1]对应的内核对象受信

                            break;

         }

参数bWaitAllFALSE的时候,WaitForMultipleObjects函数从索引0开始扫描整个句柄数组,第一个受信的内核对象将终止函数的等待,使函数返回。

实例二:

for(int i=0;i<6;i++)
{
   for(int j=0;j<10;j++)
   {
    theport[j].rmt_host=rmt_host;
    theport[j].p=port[i*10+j];
    theport[j].n=j;
    Thread[j]=AfxBeginThread(pScan,(LPVOID)&theport[j]);
    hThread[j]=Thread[j]->m_hThread;
    Sleep(1);
   }
   WaitForMultipleObjects(10,hThread,TRUE,120000);
}

注:线程退出后,即线程对象计数值变为0后,线程才会变为受信状态。

 

 

 

 

 

WaitForMultipleObjects用法探索

WaitForMultipleObjectsWindows中的一个功能非常强大的函数,几乎可以等待Windows中的所有的内核对象(关于该函数的描述和例子见MSDN,)。但同时该函数在用法上却需要一定的技巧。
                       

原型DWORD WaitForMultipleObjects(        
 DWORD nCount,                   
 const HANDLE* lpHandles,                     
 BOOL bWaitAll,                 
 DWORD dwMilliseconds               
);

                       

 
                       

WaitForMultipleObjects等到多个内核对象的时候,如果它的bWaitAll 参数设置为false。其返回值减去WAIT_OBJECT_0 就是参数lpHandles数组的序号。如果同时有多个内核对象被出发,这个函数返回的只是其中序号最小的那个。
                       

问题就在这里,我们如何可以获取所有被同时触发的内核对象。举个例子:我们需要在一个线程中处理从完成端口、数据库、和可等待定时器来的数据。一个典型的实现方法就是:用WaitForMultipleObjects等待所有的这些事件。如果完成端口,数据库发过来的数据量非常大,可等待定时器时间也只有几十毫秒。那么这些事件同时触发的几率可以说非常大,我们不希望丢弃任何一个被触发的事件。那么如何能高效地实现这一处理呢?
                       

MSDN中有一句非常重要的描述,它可以说是WaitForMultipleObjects用法的精髓:The function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When bWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected.
                       

多个内核对象被触发时,WaitForMultipleObjects选择其中序号最小的返回。而WaitForMultipleObjects它只会改变使它返回的那个内核对象的状态。
                       

这儿又会产生一个问题,如果序号最小的那个对象频繁被触发,那么序号比它大的内核对象将的不到被出理的机会。
                       

为了解决这一问题,可以采用双WaitForMultipleObjects检测机制来实现。见下面的例子:
                       

DWORD WINAPI ThreadProc(LPVOID lpParameter)

{

    DWORD dwRet = 0;

    int   nIndex = 0;

    while(1)

    {

        dwRet = WaitForMultipleObjects(nCount,pHandles,false,INFINITE);

 

        switch(dwRet)

        {

        case WAIT_TIMEOUT:

            break;

        case WAIT_FAILED:

            return 1;

        default:

            {

                nIndex = dwRet - WAIT_OBJECT_0;

 

                ProcessHanlde(nIndex++);

                //同时检测其他的事件

                while(nIndex < nCount)

                {

                    dwRet = WaitForMultipleObjects(nCount - nIndex,&pHandles[nIndex],false,0);

 

                    switch(dwRet)

                    {

                    case WAIT_TIMEOUT:

                        nIndex = nCount; //退出检测,因为没有被触发的对象了.

                        break;

                    case WAIT_FAILED:

                        return 1;

                    default:

                        {

                            nIndex = dwRet - WAIT_OBJECT_0;

                            ProcessHanlde(nIndex++);

                        }

                        break

                    }

                }

            }

            break;

        }

    }

    return 0;

}


                       

评论 (1)

parsen christion 的图片
parsen christion - 2008年 11 月 21 日
函数WaitForMultipleObjects整理
DWORD WaitForMultipleObjects(  DWORD nCount,  const HANDLE* lpHandles,  BOOL bWaitAll,  DWORD dwMilliseconds);
其中参数
nCount 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64)
HANDLE 句柄数组的指针。
HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore )数组
BOOL bWaitAll 等待的类型,如果为TRUE 则等待所有信号量有效在往下执行,FALSE 当有其中一个信号量有效时就向下执行
DWORD dwMilliseconds 超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。
举个例子:当 bWaitAll参数为FALSE 可以等待其中之一的事件
HANDLE m_hEvent[2]; 
//两事件
m_hEvent[0]=::CreateEvent(NULL, FALSE, FALSE, NULL);
m_hEvent[1]=::CreateEvent(NULL, FALSE, FALSE, NULL);
::CreateThread(NULL, 0, MyThreadProc, this, 0, NULL);
DWORD WINAPI MyThreadProc(LPVOID lpParam)
{
while(TRUE)
 {  //每次等500毫秒
 int nIndex = ::WaitForMultipleObjects(2, pThis->m_hEvent, FALSE,500);  
 if (nIndex == WAIT_OBJECT_0 + 1)
 {
 //第二个事件发生   //ExitThread(0);   //break; 
}
 else if (nIndex == WAIT_OBJECT_0) //第一个事件发生 
{
  //第一个事件
   } 
else if (nIndex == WAIT_TIMEOUT) //超时500毫秒 
{   //超时可作定时用 
}
}
 ::OutputDebugString("线程结束. /n");
 return 0L;}
当要处理第一个事件时,你只需执行SetEvent(m_hEvent[0]);
即可进入第一个事件的位置
当要执行第二个事件时执行SetEvent(m_hEvent[1]); 
 当 bWaitAll参数为TRUE 等待所有的事件
 DWORD WINAPI MyThreadProc(LPVOID lpParam)
{ while(TRUE)
 {  //每次等500毫秒 
int nIndex = ::WaitForMultipleObjects(2, pThis->m_hEvent, TRUE,500);  
  if (WAIT_OBJECT_0 + 1<= nIndex <= WAIT_OBJECT_0) //所有事件发生
 {
  //所有的信号量都有效时(事件都发生)其中之一无效。
 }
 else if (nIndex == WAIT_TIMEOUT) //超时500毫秒 
{   //超时可作定时用  }
 }
return 0L;}
必须同时执行以下两个事件才可以(只执行一个无效)
SetEvent(m_hEvent[0]);
SetEvent(m_hEvent[1]);

相关文章推荐

线程同步 等待函数 WaitForSingleObject WaitForMultipleObjects

WaitForSingleObject WaitForMultipleObjects WaitForInputIdle MsgWaitForMultipleObject WaitForDebugEve...

在用户线程/主线程中推荐MsgWaitForMultipleObjects代替WaitForSingleObject和WaitForMultipleObjects()函数

多线程同步,采用WaitForSingleObject和WaitForMultipleObjects()函数出现卡死现象,采用MsgWaitForMultipleObjects代替可以解决此类问题。

串口 WaitForSingleObject 和 WaitForMultipleObjects函数

转载自:http://blog.sina.com.cn/s/blog_9d83957001012ngk.html WaitForSingleObject 和 WaitForMultipleObj...

WaitForSingleObject以及WaitForMultipleObjects 函数

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。   WaitForSingleObject 函数 DWORD WaitForSingleObject( ...

WaitForSingleObject 和 WaitForMultipleObjects函数

WaitForSingleObject 和 WaitForMultipleObjects: 1.WaitForSingleObject  等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变...

关于WaitForMultipleObjects函数监测事件状态的问题

多个内核对象被触发时,WaitForMultipleObjects选择其中序号最小的返回。而WaitForMultipleObjects它只会改变使它返回的那个内核对象的状态。 这儿又会产生一个问题...

WaitForSingleObject、WaitForMultipleObjects、CreateThread

/////////////////////////////////////////////////////////////////////////////// 用户模式的等待 WaitForSingl...

how to implement WaitForMultipleObjects in linux

long PredictThread(const Array2D &X) //For generating members matrix only { if (X.dim2()!=m_NumV...

串口 WaitCommEvent 、GetLastError、ClearCommError、WaitForMultipleObjects的联合使用

转载自:http://www.360doc.com/content/13/0730/10/12120859_303508965.shtml 在串口程序中的几个函数的联合使用 一...

在主线程中慎用WaitForSingleObject (WaitForMultipleObjects) --代替方法:MsgWaitForMultipleObjects

在主线程中慎用WaitForSingleObject (WaitForMultipleObjects) 下面的代码我调试了将近一个星期,你能够看出什么地方出了问题吗? 线程函数: ...
  • ttgoo
  • ttgoo
  • 2011-10-12 20:41
  • 694
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)