Linux 五种IO模型(形象生动的例子)

引言

在学习五种IO模型之前,我们先看这样一个例子:大家都钓过鱼吧,钓鱼最主要的步骤实际就两个:1. 等
2. 拉杆。 钓鱼的时候你会发现有这样几种人:
张三(此人比较沉闷安静):就一直紧紧盯着鱼钩,一动不动,谁也不理,有鱼就拉杆
李四(此人生性活泼好动):在等鱼的时候,一会去找张三聊天,“嘿,哥们,钓几条鱼了”,张三不理他,一会玩玩手机,然后去看看鱼钩,又去找张三聊天,又玩玩手机,看看鱼钩…
王五(此人非常非常机智):在鱼竿处挂了一个铃铛,然后就去做自己的事情了,铃铛响拉鱼竿,铃铛不响就一直做自己的事情
赵六(此人是个土豪):开着大卡车来钓鱼,放了一百个鱼竿,哪个杆有鱼拉哪个杆
田七(此人是个大土豪):专车司机来送,他告诉司机,你去给我钓鱼,我要回去处理事情,顺便给司机一个盆,一个电话,等盘满了给我打电话就行。然后就开着车走了

上面五个人各有各的特点,但都有共同点,比如,前四个人在钓到鱼之后做的事情都一样,也就是拉杆,但钓到鱼之前做的事情不一样,有的做自己事情,有的一直等,还有的可以增加钓到鱼的概率。

一定记住:IO分两步:1. 等 2. 数据搬迁(数据拷贝)

阻塞IO

实际上,阻塞也分为两步:1. 设置为非R状态 2. 添加到等待队列中
阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。
字面意思实际就可以理解:如果此时没有数据,就一直在这等待阻塞,直到有数据为止才返回。

想一想是不是和上面张三是一样的,一直在死等鱼的到来,谁来理我都不管,对外界不闻不问,没有鱼我就等,等到鱼上钩的时候才继续往下
在这里插入图片描述

非阻塞IO

正好与阻塞IO相反,如果没有数据,不会死等,而是立即返回,去做自己的事情,等一段时间再来看是都有数据,如果还是没有,继续做自己的事情…

想想上面例子的李四,是不是就是这样,如果没有鱼,我就玩玩手机,找张三说说话,虽然张三不理他,过段时间,看看是否有鱼上钩,如果没有,继续玩玩手机,找张三,还是不理他…在这里插入图片描述

a.非阻塞式IO往往需要我们系统不能阻塞的等待数据,需要向下进行一些必要的逻辑
b.由于非阻塞的原因,往往需要轮询的方式来进行调用。
c. 可以看到非阻塞式并没有一直阻塞在系统调用,而是不断返回,但是只有数据从内核拷贝到用户才返回成功

信号驱动IO

顾名思义:也就是如果有数据的时候,就通知一下进程(给进程发个信号),说我有数据了,你来拷贝吧。

上面例子的王五就是这样干的,挂了一个铃铛,就相当于信号,当铃铛响的时候就表示鱼到了,就去拉鱼竿。
在这里插入图片描述

a. 信号驱动IO是通过信号的捕捉来提示数据准备好了,而不是IO胸痛调用自己去等待,这样就节省了大量的等待时间
b. 信号驱动只花费了将数据从内核拷贝到用户空间的时间

多路复用/多路转接IO

多路复用IO实际上就是同时监控大量的文件描述符,哪个就绪就处理哪个。
这实际上就是我么使用到的 select

和上面赵六的做法是不是就是一样的,同时放很多个鱼竿,哪个鱼竿有鱼就收哪个
在这里插入图片描述

a. 可以看到IO多路复用似乎和阻塞式没有什么不同,都是先等待数据的准备,然后将数据从内核拷贝到用户。
b. 但是可以发现select可以监听多个文件描述符的就绪

异步IO

异步IO就是我把事情都交给别人做,等完成了,给我个信号(不负责数据的拷贝)

上述田七的做法就是异步IO,给司机个盆,电话,等盆满的时候就给田七打个电话
在这里插入图片描述

a. 可以看到异步IO是在内核拷贝到用户空间之后,才通知应用程序,你该去处理数据了。

总结

a. IO分为两步:第一步 等,第二步数据拷贝
b. 前四种IO都是同步IO,都需要进行等,只不过等的方式不一样,并且任务都是自己发起,自己等待,最后自己拷贝

这篇博客只是帮助简单分辨,关于select 和 epooll,博主会在下一篇博客中给出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值