2013-03-04 75 views
3

看来有时WaitForSingleObject将等待超时,即使事件已发出信号。WaitForSingleObject为什么会错过一个信号?

信号线程每次从SetEvent()收到成功。然而,被发信号的线程并不总是会听到信号。如果我向信号线添加冗余SetEvent(),问题就会消失。

很明显,这里有什么不对劲。可能的原因是什么?

// Signalling Thread 
if (SetEvent(waitEvent)) 
    consoleprintf(L"\r\nEvent Set."); 

而应该等待的延迟时间得到通知。但并不总是显示信号。

waitEvent = CreateEvent( 
    NULL,    // default security attributes 
    FALSE,    // auto-reset event 
    FALSE,    // initial state is nonsignaled 
    TEXT("WaitEvent") // object name 
    ); 

for(;;) 
{ 
    dwWaitResult = WaitForSingleObject(waitEvent, // event handle 
     5000);  

    switch (dwWaitResult) 
    { 
    // Event object was signaled 
    case WAIT_OBJECT_0: 
     consoleprintf(L"\r\nSuccess."); 
     break; 

    case WAIT_FAILED: 
    //break; 
    case WAIT_ABANDONED: 
     consoleprintf(L"\r\nWait failed."); 
     break; 
    case WAIT_TIMEOUT: 
     consoleprintf(L"\r\nWait Timed out: %d", waitTime); 
     break; 
      default: 
     break; 
    } 
} 
+0

有问题的线程上的'ResetEvent'和'WaitForSingleObject'之间的侧线上没有'SetEvent'。这与您的描述和提及的行为的可能原因相匹配。 – 2013-03-04 22:40:14

+2

另外,相反,在'WaitForSingleObject'之后立即调用'ResetEvent' - 否则在控制台打印期间发生的Set可能会被重置破坏。 – 2013-03-04 22:50:43

+0

@ 500-InternalServerError即使事件被自动重置,也存在此问题。这仍然有意义吗? – MandoMando 2013-03-04 22:58:25

回答

14

由于您正在创建一个已命名的事件,因此该事件可以被其他知道该名称的进程访问。该另一个进程也可能正在等待事件,导致它吃掉信号。除非有其他原因需要其他进程可见,否则您应该通过NULL作为事件名称。这会创建其他进程无法访问的匿名事件。

请注意,如果给事件起一个名字,那么您将遇到问题,如果您的程序的两个副本正在运行,它们都将使用相同的事件,这将导致同样的问题。

+0

常见错误。 CreateEvent的文档曾经在NT4的日子里发臭。 – Joshua 2016-06-01 15:22:12

相关问题