现在的位置: 首页 > 综合 > 正文

完成端口的简单理解

2013年03月13日 ⁄ 综合 ⁄ 共 940字 ⁄ 字号 评论关闭

 完成端口(I/O Completion Port)据说是目前最复杂的IO模型,看了整整一天才看出个名堂来,趁现在赶快记下来,不然过两天又要忘了。

完成端口是Windows平台的异步I/O处理技术,可以极大的提升高频度IO处理的性能,尤其是在连接量较大的Web-Server中应用尤其广泛。传统的Socket处理都是利用多线程来处理,但是当请求数量过多导致线程数量也较大的时候,就会降低系统的性能--也许这有点违背我们的直觉:多线程不是可以提升系统性能吗?当线程数量不多的时候的确是这样的,但是大量的线程的存在会导致操作系统耗费在线程上下文切换上的时间迅速增加,所以多线程对于性能不会提升多少。完成端口就是充分利用Win32异步IO机制来解决这个问题的。有两点比较关键:

1、异步IO

在IO请求方,我们可以使用不阻塞的异步WSA-API来代替传统阻塞且串行的Socket-API,从而大大的增加IO交互过程的灵活性(无需等待)。那么这些异步的io操作实际上就成为一个请求消息队列,就好像发送了一个批处理到IO处理端,而这个通讯渠道正是完成端口。也就是说,我们在代码中操作IO请求时,只是一次性发出n个io请求到windows系统,没有直接进行io处理,所以也就无需专门的处理了,如新开线程,以及阻塞的IO等待。

2、线程池

在IO处理方,接受到的只是IO请求端发送过来的一系列的IO请求,就好像接到了任务列表。传统的Socket往往是一个线程处理一个任务,但是我们可以仿照工厂的流水线,对于一个任务列表,可以只使用固定的几个线程处理,即线程池。这样就引入了池的优点--极大的控制了线程数量的增长,同时也提高了线程的利用率。

完成端口实际上是IO请求方与IO处理方的一个松散耦合模型(仅通过一个消息FIFO通讯),IO请求方定制一个IO处理列表发送给完成端口,然后完成端口进行线程的池化处理,同时IO请求方可以进行其他操作;处理方处理完毕后IO处理端向消息FIFO中添加一个标志“操作完成”的消息(从此得名)通知请求者。有点类似于DMA。

当中比较关键的一点就是线程池的线程数量,理论上应该于CPU数量一致,以防止线程切换带来的开销。所以完成端口一般在多CPU的Server端考虑。

如转载请注明出处

抱歉!评论已关闭.