WaitForMultipleObjects等待多个事件的时候,如果同时有多于一个事件被触发,该如何处理所有事件呢?SDK里面讲,如果在WaitForMultipleObjects调用期间,有不止一个事件被触发,则该函数的返回值为触发的多个事件中索引值最小的那个事件的索引,这个索引减掉WAIT_OBJECT_0即可得到该事件的真正索引,从而处理这个事件。
但是一起触发的其他事件如何处理呢?有没有被丢弃呢?会不会丢失事件啊?

解决方案 »

  1.   

    DWORD WaitForMultipleObjects(
      DWORD nCount,
      const HANDLE* lpHandles,
      BOOL bWaitAll,
      DWORD dwMilliseconds
    );bWaitAll
        [in] If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is signaled. If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return value indicates the object whose state caused the function to return.bWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。
      

  2.   

    Use bWaitAll=TRUE, or use WiatForSingleObject with timeout set to 0 to check the state of an object.
     
    If WaitForMultipleObjects were not all-or-nothing in this way, you would probably end up with deadlocks. Be careful when you use wait functions.
      

  3.   

    不会丢。那这个函数不是完蛋了。HANDLE dwHandles[2];
    dwHandles[0] = XXX1;
    dwHandles[1] = XXX2;
    bWaitStatus = WaitForMultipleObjects(2,  dwHandles, FALSE,INFINITE);  
    switch (bWaitStatus)
    {
    case WAIT_OBJECT_0:
        // do something...
        break;
    case WAIT_OBJECT_0 + 1:
        // do something...
        break;
    default:
        break;
    }
      

  4.   

    To lixiaosan(小三):
      英文俺还看得懂好不好,看清题目再回答吧,摘一段Platform SDK有什么意思呢,大家都会看!
    建议你再看看这段:
      “If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signaled during the call, this is the array index of the signaled object with the smallest index value of all the signaled objects.”
    To jiangsheng(蒋晟.Net[MVP]):
      MVP就是MVP,一句话点中要害,"use WiatForSingleObject with timeout set to 0 to check the state of an object",看来如果多个handle一起触发,处理起来真的好麻烦啊,要从返回的索引开始一个一个的向后测试才能知道到底有那几个handle触发。To Atomictry(天影):
      你这代码能处理2个handle一起触发吗?狂汗 !
      

  5.   

    对于WaitForMultipleObjects函数,我在串口通信中使用很正常,我的程序需要把50兆的HEX文件写入到手机,串口的读写事件同时到达的几率应该比普通的应用程序大的多了去了。你在MSDN中搜索“WaitForMultipleObjects”,标题叫做“Waiting for Multiple Objects”,它已经给你展示了一个示例。
      

  6.   

    To Atomictry(天影):
      也就是基本不用考虑多个事件同时触发的情形吗?
      

  7.   

    那两段英语跟你的问题关系不大。
    应该不会丢,应该是使用ResetEvent信号才会重值
      

  8.   

    个人觉得应该不会丢失,楼主做个试验就知道了(我这台机器没有编译器):HANDLE Handles[2];
    Handles[0] = CreateEvent(NULL, FALSE, TRUE, NULL);
    Handles[1] = CreateEvent(NULL, FALSE, TRUE, NULL);
    WaitForMultipleObjects(2,  Handles, FALSE,INFINITE);//如果这里没有死锁就说明没有丢失啦
    WaitForMultipleObjects(2,  Handles, FALSE,INFINITE);
      

  9.   

    我觉得如果CreateEvent的时候bManuelReset为TRUE的话就不会丢,因为如果两个一起来,两个Event都是singled,如果仅处理第一个,那么第二个还是singled,在下次wait的时候还是可以得到,但如果bManuelReset为FALSE的话,恐怕会丢吧?
      

  10.   

    To SeekTruth(鹤舞白沙):
    当然在单处理器系统里,多个事件一起触发几乎是不可能的,但是smp系统呢?超线程系统呢?我现在的机器就是超线程的,是不是该考虑这个问题呢???To lsgt():
    你说的很有道理!
      

  11.   

    不会丢失,有实例为证:#include <windows.h>int main(void)
    {
    HANDLE Handles[2];
    Handles[0] = CreateEvent(NULL, FALSE, TRUE, NULL);
    Handles[1] = CreateEvent(NULL, FALSE, TRUE, NULL); printf("开始第一次等待...");
    printf("完成[%d]。\n开始第二次等待...", WaitForMultipleObjects(2,  Handles, FALSE,INFINITE)-WAIT_OBJECT_0); //如果这里没有死锁就说明没有丢失啦
    printf("完成[%d]。\n开始第三次等待...", WaitForMultipleObjects(2,  Handles, FALSE,INFINITE)-WAIT_OBJECT_0); WaitForMultipleObjects(2,  Handles, FALSE,INFINITE);
    printf("完成。");
    }编译后输出:
    开始第一次等待...完成[0]。
    开始第二次等待...完成[1]。
    开始第三次等待...
      

  12.   

    嗯,是的,如果Event没有处理也就不会手动设为未传信,如果为未传信状态那下次WaitXXXX的时候当然就会直接返回了.
      

  13.   

    SORRY,刚才仔细看了一下MSDN,发现我上面说的有误,无论bManualReset为YSE或NO都不会丢失: 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.
      

  14.   

    这样一来要处理就比较简单了,做个循环就可以了:HANDLE Handles[2];
    Handles[0] = CreateEvent(NULL, FALSE, TRUE, NULL);
    Handles[1] = CreateEvent(NULL, FALSE, TRUE, NULL);
    while( TRUE )
    {
        switch(::WaitForMultipleObjects(2,  Handles, FALSE,INFINITE))
        {
            case WAIT_OBJECT_0:
                // do some thing...
                break;
            case WAIT_OBJECT_1:
                // do some thing...
                break;
            ...
        }
    }
      

  15.   

    基本的就是这样了,多线程本身就是一个头疼的,在多cpu上更是~~~~~~~~~~~
      

  16.   

    应该是handle[0]与handle[1]都被设为singaled了,直接查各event的状态不就可以了吗.使用waitforsingobject,超时设为0,就可直接查此event是否有信号.
    HANDLE Handles[2];
    Handles[0] = CreateEvent(NULL, FALSE, TRUE, NULL);
    Handles[1] = CreateEvent(NULL, FALSE, TRUE, NULL);
    WaitForMultipleObjects(2,  Handles, FALSE,INFINITE);
    int flag = 0;
    for(int i=0; i<2; i++)
    {
    if(waitforsingleobject(Handle[i], 0)!=WAIT_TIMEOUT)
    flag |= 1<<i;
    }
    //然后根据flag的值处理:1为Handle[0]有singal,2为Handle[1]有singal,3为两个都有
      

  17.   

    蒋老大说的对 可以参见Win32多线程程序设计