我想使用线程池来启动/取消重叠的读取操作 - 分别使用ReadFile()
和CancelIo()
- 以及在读取操作完成时处理任何完成端口事件。
CancelIo()
限制)我不确定如何实现这一点。一个通常调用GetQueuedCompletionStatus()
等待完成端口事件,WaitForSingleObject()
等待正常事件,但不清楚如何混合两者。如果PostQueuedCompletionStatus()
允许我指定要唤醒的特定线程,我将被设置。有什么想法吗?
更新:解决方案必须在Windows XP上运行。不幸的是,这排除了使用CancelIoEx()
或GetQueuedCompletionStatusEx()
。
答案 0 :(得分:3)
1和2很简单,只需使用IO完成端口。
但是,你已经发现3个需要(在Windows V6 1 之前)相同的线程。
如果使用Windows> = V6,GetQueuedCompletionStatusEx
包含一个可变选项,将导致它返回是在线程上执行APC。因此,当您需要该特定线程执行其他工作时,请使用QueueUserAPC
对无操作APC 1 进行排队。您当然需要一些线程安全队列来为中断的线程提供取消内容的说明。
如果需要更早的版本兼容性,那么事情变得更加困难。可能性:
使用GetQueuedCompletionStatus
](http://msdn.microsoft.com/library/aa364986)的超时参数定期返回以检查取消。
或者,可能更实际地,将线程池分成两组。启动和取消IO的线程。其余时间这些线程等待发出信号以执行其中一个操作。池的另一部分使用GetQueuedCompletionStatus
等待IO完成。
这些都不是很好,但旧版本总是存在问题:它们缺乏功能。
1 使用无操作APC而不是在APC中工作,因此可以绕过对APC中可以执行的操作及其并发性并发问题的限制。 (由于APC是在一个线程上执行的,所以线程保持的任何锁都保存在APC中,任何受保护的状态都将是任意不一致的。)