再讲IO模型之前,给大家举一个钓鱼的例子。
张三去钓鱼,他钓鱼的时候一动不动,一直看着鱼竿,看有没有动,无论是谁叫他,他都不动,只有等鱼梢动了(鱼上钩了),他才会动
李四去钓鱼,他没有像张三那样瓷楞着,只是时不时的轮询检查鱼竿有没有动。一直在动。
王五也来钓鱼,他就比较聪明了,在鱼竿上挂个铃铛,只要铃铛响了,就代表鱼上钩了,否则他就干自己的事,不用去检查鱼竿有没有动,因为铃铛会提醒他
这时,土豪的赵六也来了,他带了100个鱼竿,叫了一群人,把鱼竿放到水里,只要鱼上钩了 ,就把它钓上来,这样,鱼上钩的几率就会变大
田七也来钓鱼了,刚打算钓的时候,突然接到电话说公司有事要回去处理,然后田七就让司机帮忙钓,最后钓到的鱼还是属于田七的。
通过上边五个人钓鱼的例子,我们依次介绍五种IO模型
IO = 等(等鱼上钩) + 数据拷贝(把鱼竿拉起)
– 阻塞IO
– 非阻塞IO
-
如果内核还未把数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码。(李四轮询检查鱼竿有没有动)
-
非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一 般只有特定场景下才使用.
– 信号驱动
- 内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。(王五在鱼竿上挂了一个铃铛)
– IO多路转接(important!!!)
- 虽然从流程图上看和阻塞IO类似,实际最核心在与IO多路转接能够同时等待多个文件描述符的就绪状态。(土豪赵六拿100个鱼竿钓鱼)
– 异步IO
- 由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序开始拷贝数据)(田七让司机帮钓)
– 小结
- 任何IO过程中,都包含两个步骤:等+数据拷贝。而在实际的应用场景中,等待小号的时间大于拷贝的时间
- 让IO高效的核心办法就是让等待时间减小。
- 阻塞IO和非阻塞IO的区别?(前者一直等待,后者轮询完返回)