首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

WaitForMultipleObjects()会丢失没来得及处理的通知.为什么?该怎么处理

2014-07-18 
WaitForMultipleObjects()会丢失没来得及处理的通知.为什么?WaitForMultipleObjects会丢失没有及时处理的

WaitForMultipleObjects()会丢失没来得及处理的通知.为什么?
WaitForMultipleObjects会丢失没有及时处理的信号。是这样的吗?
步骤:
1. 我创建两个waitable timer,用WaitForMultipleObjects来等待他们。
2. while循环里面,信号到来的时候分别打印一条接受语句。这个没有问题。
3. 第一个timer接收到信号的时候,打印一个消息。
  第二个timer接收到信号,进入一个占用cpu100%的循环一段时间(一亿次计算),

  我发现,这个程序不能从Wait函数得到第一个Timer的全部响应了,虽然Wait优先返回所有有信号的句柄的第一个。
  也就是说,第一个Timer的信号响应,丢掉了一半(从运行结果可以看出来).
  这到底是为什么呢? 各位大哥帮我分析分析,是我程序本身的问题,还是WaitForXXX系统调用本身的弱点!

(昨天我用另外一个帐号贴过,但是当时给的代码不对,不好意思啊http://topic.csdn.net/u/20120213/15/fb4eda64-3ab8-4d06-9369-c4dab434b3e4.html)

源代码是:

C/C++ code
int main(void){    HANDLE hTimer[2];    hTimer[0]=CreateWaitableTimer(NULL,FALSE,"myTimer0");    hTimer[1]=CreateWaitableTimer(NULL,FALSE,"myTimer1");    LARGE_INTEGER liDueTime;    liDueTime.QuadPart = -30000000;//3s to trigger 1st timer.     if(!SetWaitableTimer( hTimer[0], &liDueTime, 2000, NULL, NULL, FALSE)){        printf("fail 1\n");    }    if(!SetWaitableTimer( hTimer[1], &liDueTime, 5000, NULL, NULL, FALSE)){        printf("fail 1\n");    }    while(1){        DWORD ret=WaitForMultipleObjects(_countof(hTimer),hTimer,FALSE,INFINITE);        printf("Signalled\n");        if(ret==WAIT_OBJECT_0){            printf("2s timer begin\n");            for(unsigned i=0;i<1000000000;++i){//Time consuming part                float j=i*2.2f;                float k=j+1;            }//End time consuming part            printf("2s timer end\n");        }        else if(ret==WAIT_OBJECT_0+1){            printf("5s timer begin\n");        }        else{            printf("error!\n");            return 1;        }    }    return 0;}

我期待的结果是:
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
1s timer begin
Signalled

但是实际的结果是:
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin
Signalled
2s timer begin
2s timer end
Signalled
1s timer begin


[解决办法]
1. 当你处理 Time consuming part 时如果有多次timer signed,比如timer1 signed了两次那就会丢一次,解决方法是新开一个线程去处理耗时操作;

2. 因为这儿WaitForMultipleObjects只要等到一个timer signed就会返回,如果这时候两个timer都signed了你可能就会丢掉第二个timer。可以嵌套一个WaitForSingleObject来解决这种case:
C/C++ code
        DWORD ret=WaitForMultipleObjects(_countof(hTimer),hTimer,FALSE,INFINITE);        printf("Signalled\n");        if(ret==WAIT_OBJECT_0){            DWORD ret1=WaitForSingleObjects(hTimer[1], 0);            if (ret==WAIT_OBJECT_0)            {              printf("5s timer begin\n");            }            printf("2s timer begin\n");            //Create a new thread to handle consuming part            printf("2s timer end\n");        }        else if(ret==WAIT_OBJECT_0+1){                  printf("5s timer begin\n");        }        else{            printf("error!\n");            return 1;        }
[解决办法]
DWORD ret=WaitForMultipleObjects(_countof(hTimer),hTimer,FALSE,INFINITE);
----------
如果同时有多个Timer的signal状态的话,WaitFor函数返回的是第一个,你后面需要循环检测后续的Timer是否也是signal状态。


[解决办法]

探讨
引用:
1. 当你处理 Time consuming part 时如果有多次timer signed,比如timer1 signed了两次那就会丢一次,解决方法是新开一个线程去处理耗时操作;

2. 因为这儿WaitForMultipleObjects只要等到一个timer signed就会返回,如果这时候两个timer都signed了你可能就会丢掉第二个……

[解决办法]
hTimer[0]=CreateWaitableTimer(NULL,TRUE,"myTimer0");
hTimer[1]=CreateWaitableTimer(NULL,TRUE,"myTimer1");

热点排行