http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx
根据msdn,在备注部分,它指出: “如果设置定时器的线程终止并且存在关联的完成例程,则取消定时器。但是,定时器的状态保持不变。如果没有完成例程,则终止线程对计时器。“
然后再往下说: “如果调用SetWaitableTimer的线程退出,则取消定时器。这会在定时器设置为信号状态并取消未完成的APC之前停止定时器;它不会更改定时器的信号状态。 “
因此我的问题, 如果我有一个线程调用SetWaitableTimer而没有关联的完成例程,另一个线程调用WaitOnMultipleObjects(传入定时器对象句柄)并且调用SetWaitiableTmer的线程此后不久退出,那么定时器对象是否会被取消,或者它会在周期时发出信号到期?
答案 0 :(得分:3)
文档有点不清楚。我认为你能做的最好的就是自己测试一下。但我相信只有在使用I / O完成例程时,定时器才会自动取消。
我可以提供关于Windows APC的一些“理论”背景,以证明我(受过教育的)猜测。
APC =“异步程序调用”。在Windows中,每个用户模式线程都配备了一个所谓的APC队列,这是一个必须在该线程上调用的系统管理的过程队列。线程可以进入所谓的“可警告等待”状态(故意),在此期间它可以执行该队列中的一个或多个过程。您可以手动将过程调用放入APC队列,也可以发出I / O,完成后会将过程调用“放入”。
简单来说,方案如下:您发出几个I / O,然后等待其中任何一个完成(或失败),或者可能还有其他一些事件。然后,您可以调用其中一个警报等待功能:SleepEx
,WaitForMultipleObjectsEx
或类似功能。
重要说明:此机制旨在支持单线程并发。也就是说,同一个线程发出几个I / O,等待某些事情发生,并做出适当的响应。所有APC例程都保证在相同的线程中调用。因此 - 如果这个线程退出 - 没有办法调用它们。因此 - 所有未完成的I / O也取消。
有几种Windows API函数可以处理异步I / O,而它们允许选择几种完成机制(例如ReadFileEx
):APC,设置事件或在I /中完成O完成端口。如果这些函数与APC一起使用 - 如果发出的线程退出,它们会自动取消I / O.
因此,我猜这个等待计时器只有在与APC一起使用时才会自动取消。
答案 1 :(得分:3)
直接从等待计时器的实现中提供更多信息:如果使用CompletionRoutine,则计时器将放置在链接列表中的链接列表中,该链接列表称为SetWaitableTimer。当线程终止时,内核遍历垂死线程的链表,取消的是仍在排队的计时器。
如果您没有使用完成例程,则计时器永远不会添加到任何线程的链接列表中,因此在任何特定线程死亡时不会取消。