【问题标题】:WaitForSingleObject times out too fastWaitForSingleObject 超时太快
【发布时间】:2012-04-25 13:51:09
【问题描述】:

我在辅助线程中有这段代码:

DWORD result = WaitForSingleObject(myhandle,10000);
if(result == WAIT_OBJECT_0){
    AfxMessageBox(_T(...));
}
else if(result  == WAIT_TIMEOUT){

    AfxMessageBox(_T("Timeout"));
}

有时,并非总是如此,几乎会在调用 WaitForSingleObject 时立即调用超时(甚至不会延迟 1 秒)。

我做错了吗?对更稳定的替代品有什么建议吗?


编辑:

myhandle 在类构造函数中创建为:

myhandle = CreateEvent(NULL,FALSE,FALSE,_T("myhandle"));

它会被另一个函数调用:

SetEvent(myhandle);

关键是它在我执行 SetEvent 时有效,问题是它有时会在调用 WaitForSingleObject 时立即超时,即使它应该等待 10 秒。

【问题讨论】:

  • 你还在等什么?我的句柄从何而来?
  • 等待前后有没有检查GetLastError()

标签: c++ winapi


【解决方案1】:

你真的需要/想要一个命名事件吗?通常这仅对进程间并发控制是必需的。

如果您有此类的多个实例,它们都将使用相同的事件 - 请参阅 docs for CreateEvent 关于调用已存在的命名对象的内容。

您可能需要做的就是在此处删除名称。这允许每个类实例拥有自己的Event 对象,并且行为应该更可预测。

【讨论】:

  • 创建事件的类是单例。它是从主视图设置的:Class::instance()->SetEvent() 其中代码是SetEvent(myhandle); 我会尝试你的建议,即 CreateEvent(NULL,FALSE,FALSE,NULL)
  • 是的,但这只有在多次调用该代码时才重要。您是否运行多个程序实例?
【解决方案2】:

WaitForSingleObject 不会等待整整 10 秒。它将等待第一个:

  1. 超时值已过
  2. 事件发出信号
  3. 句柄无效(在另一个线程中关闭)

如果在您调用WaitForSingleObject 时设置了事件,则条件#2 从一开始就为真,WaitForSingleObject 立即返回。

如果你想总是等待 10 秒,你应该使用这样的代码:

//Always wait 10 seconds
Sleep(10000); 

//Test the event without waiting
if(WaitForSingleObject(myhandle, 0) == WAIT_OBJECT_0) {
    AfxMessageBox(_T("Event was set in the last 10 secondes"));
} else {
    AfxMessageBox(_T("Timeout"));
}

【讨论】:

    【解决方案3】:

    花了一些时间,但问题实际上是程序有时会多次调用WaitForSingleObject。所以是之前的调用超时了。

    解决方案是使用WaitForMultipleObjects,并在已知第一个事件不会设置的情况下设置一个取消事件,因此在重新调用之前取消计时器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 2011-10-14
      相关资源
      最近更新 更多