五种IO模型
在网络上已经有很多大佬写了很多关于IO模型的博客,我这篇主要是自己在学习中的总结,也有很多借鉴别人的地方。
IO:等待数据拷贝的过程(内核态->用户态)
现在常用的五种IO模型:阻塞型IO,非阻塞型IO,信息驱动型IO,多路转接IO,异步IO。
首先我们要搞清楚的是 什么叫 阻塞和非阻塞?
阻塞:一个函数发起了功能调用,若当时不具备完成的条件,则调用一直在等待。比如:我们去买饭,这是饭还没有做好,我们就一直在那等着,没有干别的事情。
非阻塞:一个函数发起了功能调用,若当时不具备完成的条件,则立即返回。比如,我们去买饭,这是饭还没有做好,我们就直接走了。
阻塞IO:发起了IO调用,若当时不满足IO条件,则一直等待。
比如:我们去钓鱼,扔下鱼竿后,一直拿着鱼竿等着鱼上钩。
优点:流程比较简答,一个完成后,才进行下一个。
缺点:IO未就绪就得一直等待,资源利用率较低,IO效率较低。
非阻塞IO:发起了IO调用,若当时不满足IO条件,则调用立即返回,并循环的去查看是否满足。
比如:我们在钓鱼,扔下鱼竿,发现没有鱼上钩,我们就玩了一把游戏,等游戏结束的时候,才去看鱼是否上钩,没有上钩就接着玩游戏。每次游戏结束的时候,看一眼鱼是否上钩。
优点:相比较阻塞IO,资源利用率上升。
缺点:需要循环的去查看是否满足条件,cpu占用较多,流程较为复杂一点,并且实时性不高(比如在打游戏的时候,鱼上钩了,但是我们在游戏结束了才去看的话,有可能鱼就溜走了)。
信息驱动型IO:首先我们先定义IO就绪的信号处理函数,如果我们收到了信号,证明这时候数据已经就绪了,我们就去处理。
比如:我们在钓鱼的时候,在鱼竿上绑上一个铃铛,这时候我们就去干别的事情了,当铃铛一响,证明了有鱼上钩,这时候,我们立马就去收鱼竿。
优点:相较于非阻塞,IO实时性更高,IO效率更高。
缺点:需要定义信号处理,流程较为复杂一点。
多路转接IO:使用监控函数,对大量的描述符进行监控,当有描述符就绪的时候,对于进行IO操作,未就绪的不操作,也就是说这个也属于阻塞型IO。
比如:我们在钓鱼的时候,拿了10个鱼竿,并且找了一个人,让他帮我们看着,如果某一个鱼竿动了,证明有鱼了,然他立马通知我,然后我去收鱼竿。
优点:可以同时监控大量的描述符,资源利用率高。
缺点:流程更为复杂,需要使用监控函数。
异步IO:首先我们定义一个IO完成的信息(当我们收到信息的时候,就证明IO操作已经完成,直接进行数据的处理。我们先发起IO调用,交由系统进行完成,等IO操作完成后,在由信号通知我。
比如:我们去钓鱼,这时候,我们还带了一个人,让他把鱼调到后,在通知我,我就去干别的事情了。等他调到鱼后,把鱼给我就好了。
优点:对系统的利用用最为充分,IO效率最高。
缺点:流程最为复杂。
同步:表示任务由进程自己完成,任务是顺序化完成。
异步:任务完成的流程不固定,任务由系统完成。分为异步阻塞,异步非阻塞。
异步阻塞:发起调用后,进程等着系统完成。
异步非阻塞:发起调用后,进程不等待系统的完成,调用立即返回。
同步和异步的区别:任务是由自己完成的,还是由系统完成的。(如上所说的,收起鱼的那一个动作,是由自己完成还是别人完成的呢。)因此上面的五种IO,前面四种都是同步IO,最后一个是异步IO。