【问题标题】:Why would WaitForSingleObject miss a signal?为什么 WaitForSingleObject 会错过信号?
【发布时间】:2013-02-19 04:25:03
【问题描述】:

似乎有时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;
   }
}

【问题讨论】:

  • 在有问题的线程上ResetEventWaitForSingleObject 之间的侧线程上没有SetEvent。这与您的描述和上述行为的可能原因相符。
  • 另外,相反,在WaitForSingleObject 之后立即调用ResetEvent - 否则在控制台打印期间发生的 Set 可能会被重置破坏。
  • @500-InternalServerError 即使事件被自动重置,这个问题仍然存在。这还有意义吗?
  • 那你有没有把 ResetEvent 调出来?
  • 既然你给了这个事件一个名字,那么其他一些进程可能正在吃你的信号。您创建命名事件是否有原因?尽可能使用匿名事件。

标签: c multithreading winapi synchronization waithandle


【解决方案1】:

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多