7

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx

根据msdn,在备注部分中,它指出:“如果设置定时器的线程终止并且有关联的完成例程,则定时器被取消。但是,定时器的状态保持不变。如果没有完成例程,然后终止线程对计时器没有影响。

然后再往下,它声明:“如果调用 SetWaitableTimer 的线程退出,定时器将被取消。这会在定时器设置为信号状态之前停止定时器并取消未完成的 APC;它不会更改定时器的信号状态。 "

因此我的问题是,如果我有一个线程调用 SetWaitableTimer 而没有关联的完成例程,另一个线程调用 WaitOnMultipleObjects(传入计时器对象句柄)并且调用 SetWaitiableTmer 的线程在此后不久退出,那么计时器对象会被取消还是仍然会变成期限到期时发出信号?

4

2 回答 2

4

直接从可等待计时器的实现中提供更多信息:如果您使用 CompletionRoutine,则计时器被放置在一个链表上,该链表与调用 SetWaitableTimer 的线程链接。当线程终止时,内核会遍历垂死线程的链表并取消仍在排队的计时器。

如果您不使用完成例程,则计时器永远不会添加到任何线程的链表中,因此不会在任何特定线程死亡时取消。

于 2012-06-16T19:54:19.413 回答
3

文档有些不清楚。我认为你能做的最好的就是自己测试。但是,我相信只有在使用 I/O 完成例程时,计时器才会自动取消。

我可以提供一些关于 Windows APC 的“理论”背景,以证明我的(受过教育的)猜测是正确的。

APC = "异步过程调用"。在 Windows 中,每个用户模式线程都配备了一个所谓的 APC 队列,这是一个系统管理的过程队列,必须在该线程上调用。线程可能会进入所谓的“可提醒等待”状态(故意),在此期间它可能会执行该队列中的一个或多个过程。您可以手动将过程调用放入 APC 队列,或者发出一个 I/O,它在完成时会将过程调用“放入”那里。

简而言之,场景如下:您发出多个 I/O,然后等待其中任何一个完成(或失败),也许还有其他一些事件。然后,您调用其中一个警报等待函数:SleepExWaitForMultipleObjectsEx类似函数。

重要提示:此机制旨在支持单线程并发。也就是说,同一个线程发出几个 I/O,等待某事发生,然后做出适当的响应。保证同一个线程中调用所有 APC 例程。因此 - 如果这个线程退出 - 没有办法调用它们。因此,所有未完成的 I/O 也会被取消

有几个处理异步 I/O 的 Windows API 函数,但它们允许选择几种完成机制(例如ReadFileEx):APC、设置事件或将完成放入 I/O 完成端口。如果这些函数与 APC 一起使用 - 如果发出线程退出,它们会自动取消 I/O。

因此,我猜想等待计时器只有在与 APC 一起使用时才会自动取消。

于 2012-06-16T17:06:39.243 回答