1 Epoll vs. IOCP
Epoll 和 IOCP 都是为高性能网络服务器而设计的高效 I/O 模型;都是基于事件驱动的。事件驱动有个著名的好莱坞原则(“不要打电话给我们,我们会打电话给你”)。
不同之处在于:
1. Epoll 用于 Linux 系统;而 IOCP 则是用于 Windows ;(啊,好大的鸡蛋 … )
2. Epoll 是当事件资源满足时发出可处理通知消息;而 IOCP 则是当事件完成时发出完成通知消息。
3. 从应用程序的角度来看, Epoll 本质上来讲是同步非阻塞的,而 IOCP 本质上来讲则是异步操作;这是才二者最大的不同。
就第 3 点来讲,还需要简单说说系统的 IO 模型。
2 系统的 IO 模型
系统 IO 可以分成三种模型:阻塞 (blocking) ,同步非阻塞 (non-blocking synchronous) 和异步非阻塞 (non-blocking asynchronous) 。
先举个打印室的例子:
你有个文档需要拿到打印室打印,这时候正巧你的一个同事正在打印一本 800 页的书;
看看这三种模型下你和打印室的反应。
1. 阻塞模型
调用者必须阻塞等待操作的完成,如果资源不可用,只能阻塞等待。可见这是一种相当低效的模型。
对应于打印室的例子:你把文档给打印室,打印室不会告诉你,现在前面有个兄弟 800 页呢,你的等半天了。你只能等在那里,直到打印室打完文档后给你;在打那 800 页时你也只能白等着。
2. 同步非阻塞
本质上依然是同步的,但是当资源不可用时,调用将会立即返回,并得到通知指示资源部可用;否则可以立即完成。
对应于打印室的例子:你把文档给打印室,打印室马上就会告诉你,忙着呢,现在前面有个兄弟 800 页呢。得到打印室的通知后,随你怎么处理了;如果你去的时候打印机正好空闲,打印室就会立即开始打印,把打印好的文档给你。
3. 异步非阻塞
异步肯定不会阻塞啦(有谁听过异步阻塞啊?),异步就是你告诉操作系统说,我要给你什么事情,好了,如果操作立即完成,系统会立即返回给你操作结果;否则就告诉你说执行中,完成了再通知你,你接着干自己的事情去吧,不用等在这里。
当然这个时候系统必须提供一种机制,以期能在完成时让应用程序得到通知。
对应于打印室的例子:你把文档给打印室,如果这时候打印机正好空闲,打印室就会立即开始打印,把打印好的文档给你;否则打印室会对你说,兄弟你忙去吧,文档打印好了马上通知你。
从理论上来讲异步肯定是最优的方案了,你把处理扔给操作系统就行了。