I/O完成端口的优缺点

Ben*_*min 51 windows io network-programming device-driver iocp

为什么很多人说I/O完成端口是快速而漂亮的模型?
什么是I/O完成端口的优缺点?

我想知道一些比其他模型更快的IOCP的要点.

如果你可以解释它比较其他模型(选择,epoll,传统的多线程/进程),那会更好.

Dam*_*mon 84

I/O完成端口很棒.描述它们没有更好的词汇.如果Windows中的任何内容都正确完成,那就是完成端口.

您可以创建一些线程数(实际上并不重要),并将它们全部阻塞在一个完成端口上,直到事件(您手动发布的一个事件,或来自计时器异步I/O 的事件或其他事件)到达.然后,完成端口将唤醒一个线程来处理事件,直到您指定的限制.如果你没有指定任何东西,它将假定"最多CPU核心数",这非常好.

如果已经有更多线程活动超过最大限制,它将等待其中一个完成,然后一旦进入等待状态,就将事件交给线程.此外,它将始终以LIFO顺序唤醒线程,因此很可能缓存仍然是温暖的.

换句话说,完成端口是一个毫不费力的"事件轮询"以及"尽可能多地填充CPU"解决方案.

您可以在完成端口,套接字或任何其他可等待的文件中抛出文件读取和写入.而且,如果您愿意,您可以发布自己的活动.每个自定义事件至少有一个整数和一个指针值的数据(如果使用默认结构),但实际上并不限于此,因为系统也会愉快地接受任何其他结构.

此外,完成端口很快,非常快.曾几何时,我需要从另一个线程通知一个线程.碰巧的是,该线程已经有一个文件I/O的完成端口,但它没有泵送消息.所以,我想知道我是否应该咬紧牙关并使用完成端口以简化,即使发布一个线程消息显然会更有效率.我还没有决定,所以我进行了基准测试.令人惊讶的是,事实证明,完成端口的速度提高了约3倍.所以...更快,更灵活,决定并不难.

  • @Joey Adams:我当然会说"当然",并链接到一个可以自己尝试的工作示例,但令人尴尬的是,工作示例_不起作用_.这对我来说是两次令人尴尬,因为这不仅意味着上面关于计时器的声明是错误的,而且我还要向我的老板解释我是在6个月前发布的软件中没有注意到的,并且没有在质量保证中注意到(这是为了保证在没有事件发生的情况下的最后期限,它必须在质量保证期间意外工作,因为总是有足够的其他事件可用). (15认同)
  • I/O等待通常在Windows中完成得非常好,无论是IOCP,与事件重叠,与完成例程重叠,还是等待所有上述内容同时使用信号量,完成子进程和UI消息. (6认同)
  • "......直到一个事件(手动发布的一个事件,或来自定时器或异步I/O的事件或其他事件)到达." 您确定可以使用IOCP轮询计时器吗?http://stackoverflow.com/questions/3239080的答案另有说法. (4认同)
  • 有一件好事要知道_even with ReadFile/WriteFile_你可以任意扩展OVERLAPPED结构.只需将其嵌入更大的结构中,并使用CONTAINING_RECORD检索您的额外数据. (3认同)
  • @Damon:感谢您的跟进.另一种选择是将超时传递给GetQueuedCompletionStatus.如果您的应用需要在多个位置计时,您可以使用优先级队列来跟踪到期,并让工作线程一次又一次地调用GetQueuedCompletionStatus.使用PostQueuedCompletionStatus唤醒工作线程. (2认同)

San*_*huk 13

通过使用IOCP,我们可以克服"每个客户端一个线程"的问题.众所周知,如果软件不在真正的多处理器机器上运行,性能会大幅下降.线程是既不是无限也不便宜的系统资源.

IOCP提供了一种方法,让一些(I/O工作者)线程"公平地"处理多个客户端的输入/输出.线程被挂起,在有事情要做之前不要使用CPU周期.

你也可以在这本好书中阅读一些信息http://www.amazon.com/Windows-System-Programming-Johnson-Hart/dp/0321256190

  • @Ben:老实说,我发现IOCP编程比使用重叠I/O更容易理解编程风格.如果您同时进行多个操作(就像复制文件时那样),则尤其如此. (4认同)
  • `OVERLAPPED`I/O克服了"每个客户一个线程",非常感谢你.IOCP为表带来的是(正如您正确提到的)在多个线程之间共享负载.对于大多数使用来自单个线程的OVERLAPPED I/O的应用程序来说,更简单,更高效.只有大批量应用程序服务器才应考虑IOCP. (3认同)