天天看点

IO重叠的理解

这篇文章转载于CSDN论坛的回帖里,具体作者忘记里,不过很感谢作者,感觉对我理解io重叠很有帮助,贴出来供大家参考

当CPU执行你的代码时遇上一个I/O请求[诸如读写文件之类的],系统产生一个中断,让CPU去完成这个I/O请求,等到完成了以后,系统再次产生一个中断让原先的程序继续运行。也就说通过中断保持这两者间的同步。可以将终端理解为硬件化的信号量。

这就是所谓的同步概念,一个线程中只可能同时处理一个I/O请求

你要知道,一个I/O操作是非常耗时的,当你的代码挂起后等待I/O完成的这段时间内,你的这个线程浪费了N个指令周期。

如果同时要反复读写大文件,用同步的效率是很低的。

为了解决这个问题,当CPU执行你的代码时遇上一个I/O请求后,系统这是为你开一根内部线程去处理I/O请求,并且你的线程并不挂起,但你可能会觉得如果I/O还没完成,后续的代码就算他让我执行,我也执行不下去了嘛?

如果下面的代码和这个I/O操作有关的话,那么它就要等一等,等到这个I/O操作完成,通过在一个线程中调用WaitForMultiObject()和GetOverlappedResult()就可以得到I/O完成的消息,然后再对其作相应的处理。

但如果后续的代码和这个I/O操作无关,你就可以以更快的速度之行下去了,而无需等待IO请求的完成了

这也就是异步了

你想当你有这样一个请求,就是

ReadFile(...)                                 -1

WriteFile(...)                               -2

ReadFile(...)                                 -3

你在程序中如果使用同步的话,那只有当你完成1以后2才会继续执行,2执行完以后3才会继续执行。这就是同步。

当如果使用异步的话,当系统遇到1时,OK,开一线程给它去完成该IO请求,然后系统继续运行2,3,分别开两线程。

1-2-3如果是比较耗时的操作,尤其是运用在网络上,那么1-2-3这三个IO请求是并行的,也就是重叠的。

重叠I/O就是能够同时以多个线程处理多个I/O,其实你自己开多个线程也可以处理多个I/O,当然系统内部优化以后肯定性能要比你的强,呵呵。

我只是简单的说了一下重叠[Overlapped]没从代码的角度给你分析。希望你能对重叠IO有所理解。看看Windows网络编程,上面不是有模型嘛

最后提一下重叠模型的缺点,他为每一个IO请求都开了一根线程,当同时有1000个请求发生,那么系统处理线程上下文[context]切换也是非常耗时的,所以这也就引发了完成端口模型IOCP,用线程池来解决这个问题,我就不多说了。