windows - 重叠 I/O : How to wake a thread on a completion port event or a normal event?

标签 windows iocp

我想使用线程池来启动/取消重叠读取操作——分别使用 ReadFile()CancelIo()——以及处理任何读取操作完成时的完成端口事件。

  1. 任何线程都可以发起读操作
  2. 任何线程都可以处理读取完成事件
  3. 只有发起读取的线程可以取消它(这是一个 CancelIo() 限制)

我不确定如何实现它。通常调用 GetQueuedCompletionStatus() 来等待完成端口事件,调用 WaitForSingleObject() 来等待正常事件,但不清楚如何混合使用这两者。如果 PostQueuedCompletionStatus() 让我指定一个特定的线程来唤醒我就会被设置。有什么想法吗?

更新:该解决方案必须在 Windows XP 上运行。不幸的是,这排除了使用 CancelIoEx()GetQueuedCompletionStatusEx() 的可能性。

最佳答案

1和2很简单,只需要使用IO Completion端口即可。

但是,正如您发现的那样,3 需要(在 Windows V61 之前)相同的线程。

如果使用 Windows >= V6,GetQueuedCompletionStatusEx包括一个可变选项,如果在线程上执行 APC,它将导致它返回。所以使用 QueueUserAPC当您需要特定线程执行其他工作时,将无操作 APC1 排队。您当然需要一些线程安全队列来为被中断的线程提供要取消的指令。

如果需要早期版本兼容性,那么事情就会变得更加困难。可能性:

  • 使用GetQueuedCompletionStatus]( http://msdn.microsoft.com/library/aa364986 )的超时参数定期返回检查取消。

  • 或者,更实际的做法是,将线程池分成两组。发起和取消 IO 的线程。其余时间这些线程花在等待收到执行这些操作之一的信号上。池的另一部分使用 GetQueuedCompletionStatus 等待 IO 完成。

这些都不是很好,但这始终是旧版本的问题:它们缺乏功能。

1 使用无操作 APC 而不是在 APC 中工作,这样可以绕过 APC 中可以完成的操作的限制及其固有的并发问题。 (由于 APC 是在线程上执行的,线程持有的任何锁都在 APC 中持有,任何 protected 状态都将是任意不一致的。)

关于windows - 重叠 I/O : How to wake a thread on a completion port event or a normal event?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/961343/

相关文章:

c - 为什么这个 C 程序在 windows 上崩溃而在 linux 上运行正常?

c++ - OpenGL Performer 最简单的移植路径?

c++ - 将 IOCP 与 UDP 一起使用?

c++ - 我可以使用 std::shared_ptr 来包装 IOCP 中的每个 I/O 数据吗?

c# - 每次打开应用程序窗口(其他进程)时如何执行一些代码?

windows - Powershell 获取凭据失败

c++ - 从 Linux 移植到 Windows,tm.sys

c - io完成端口问题,每个GetQueuedCompletionStatus调用多个wsarecv或wsasend

windows - 没有 ConnectEx 的 Windows 上的非阻塞套接字连接

c# - 如何调试与低级 API(如 I/O 完成端口)交互的代码?