之前在5种服务器网络编程模型讲解中说到了同步阻塞IO、IO多路复用等IO模型。
这两天一口气把《构建高性能web站点》看完了,书中关于同步阻塞IO、同步非阻塞IO、多路I/O复用、异步IO、同步、异步、阻塞、非阻塞等一些概念的例子有点意思,分享一下。
关于同步阻塞IO、同步非阻塞IO、多路I/O就绪通知、异步IO这些概念的理解,一切都要从逛街吃面开始。
同步阻塞IO
你逛街时,逛着逛着饿了,想去街边小吃店买一碗面,交了钱,可面条做出来需要时间,你也不知道面条什么时候做好,你只好坐在那里傻等,等吃完面后再继续逛街。这里的吃面条过程便可以看做是同步阻塞I/O操作,因为你交完钱后,得等面做好,然后吃完面,才能继续去逛你的街。其中做面的过程可以看做一个IO操作,你需要等待面做好才能做真正有用的事,这阻塞了你的逛街。
同步非阻塞IO
假如你不想坐着傻等面做好,你可以在店家做面的过程中不浪费时间,能继续逛街。但问题来了,为了吃上面,你得逛一会街,就跑回面馆看看面做好没有,没做好就继续去逛街,过一会再来面馆看面是否做好,如果面做好了,你就可以吃面了。这一过程便可以看做同步非阻塞IO。因为做面这一“IO过程”并没有阻塞你逛街,但是,你的代价就是不断的去轮询面馆,看面做好没有。
多路I/O就绪通知
在买面的故事中,假如你是个吃货,你不止想买一份面条,你还想买饺子、包子、稀饭等等。假设这些东西都需要时间制作,这时,你如果按同步非阻塞IO那样,不断的去轮询各个小吃店,你会累死去。好在商业街有个大显示屏,各个店家食物做好后,都会显示在大屏幕上,你现在需要做的是只要隔断时间看看大屏幕就可以了。这就是多路IO复用模型,你就一个进程,买饺子、包子、稀饭、面条分别对应着不同的IO事件,你只需要偶尔看一下电子大屏幕,就能够监听处理这些IO事件了。
异步IO
书中关于发短信通知这一做法,我觉得跟异步IO有点相似(但不能完全体现异步这个概念)。就是说你去各个店家买吃的时,顺便拿留下了你的手机号码,然后就接着逛街去了。等店家做好了后,店家通过短信通知你,此时,你就可以去吃你的各种东西了。这里你留下的手机号码就相当于注册了个回调函数,而店家通过短信通知你这一动作就相当于执行回调函数。你会发现异步IO是最省事的,你甚至不用时不时的去看电子屏幕了,逛你的街就是了,短信来了,就说明IO执行完毕。
PS:如果短信来了,是告诉你面也有人替你吃完了(进程在读写数据读写时也不发生阻塞),就是完完全全的异步非阻塞。
同步、异步、阻塞、非阻塞
这是一组很容易混淆的概念,相信很多有过网络编程经验的人对着几个概念都会有种“只可意会不可言传”的感觉。
阻塞和非阻塞是指当进程访问的数据如果尚未就绪,进程是否等待,简单来说他们的区别就相当于函数内部的实现区别,即未就绪时直接返回就是非阻塞,未就绪时等待就是阻塞。
而同步和异步是指访问数据的机制,同步一般指主动请求并等待IO完毕的方式,当数据就绪后在读写的时必须阻塞。异步则是指主动请求数据后便可以继续处理其他任务,随后等待IO操作完毕的通知,这可以使进程在读写数据读写时也不发生阻塞。