对I/O模型的一点认识

对IO模型的一点认识

I/O操作根据设备的不同分为很多种类型,比如网络IO、内存IO、硬盘IO,对于网络和硬盘IO它们比内存IO要慢很多,不管是哪种IO类型,这些IO操作都是由内核来完成。

在实现功能调用的时候通常会提到同步和异步的概念:

阻塞I/O:阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入睡眠状态)。函数只有在得到结果之后才会返回。

比如我们使用cat命令来查看一个文件内容,但是这个文件非常大,需要几秒钟才会打开,一旦cat命令发起为一个进程之后,接下来必须要等待这个文件装载进内存 所以在文件载入内存之前,必须把这个进程转为睡眠状态,I/O在后台自动完成。


I/O完成步骤:

一旦某一进程发起I/O调用之后,内核收到后立即进入响应模式,内核从磁盘中读进内核能访问到的内存空间(指的是内核独有的内存空间,而进程不能访问)

内核处理完成后则将内核内存中的数据复制到进程内存空间中,由于内核内存空间进程是不允许被访问的,因此数据被载入到内核内存空间,必须再复制才能被进程访问,这段过程为I/O完成的过程。

wKiom1LKBrXiIYZKAACUBrr8Hb8796.jpg

一般来讲文件I/O都是阻塞的,网络I/O有可能会使用非阻塞I/O模型

非阻塞:指在不能立刻得到结果之前,被调用函数不会阻塞当前线程,而会立刻返回,非阻塞状态属于忙等待状态,性能比较差


总之可以分为两段来理解:

wKioL1LKBqnCtT45AAAzvgLr6bY661.jpg

如上图所示:

第一段是内核负责将数据从磁盘装载进内核内存;

第二段是内核负责将数据从内核内存复制进进出内存;

阻塞 I/O  :一旦进程发起IO调用,于是整个进程将被阻塞了,不再执行,第一段被阻塞的,第二段也是被阻塞的 直到第二段也被处理完成,那么整个系统调用才会返回结果说白了就是一步完成,如图1所示。

非阻塞I/O :一旦发起调用,内核立即返回让其稍等,内核将数据从硬盘载入到内核内存中来,这时则处于等待状态,等待数据从内核内存复制到进程内存,直到第一步完成,所以第一段是非阻塞,而第二段是阻塞的

IO多路复用:需要调用I/O时,不会直接告知内核,而是向内核一个特殊的系统调用,使其告知哪个IO是否处理完成,这样我们的内核就可以同时处理多个I/O,如上的例子,我们的I/O会阻塞到复用调用上,所以复用这个功能会监听每个IO是否完成,如果都同时完成则可以进行下面的操作

如果一个进程调用了多个IO(如键盘IO或硬盘IO) 如果其中某一个IO执行完成而另一个IO没有处理完成,那么这个IO是处于睡眠状态,就算另一个IO完成它也不会得知,这时IO多路复用就有意义了

常用I/O复用:

select :就是IO复用器,将请求发给select ,由select来进行调用,select还可以监控调用是否结束,一旦结束则将数据发给进程,但是最多只支持1024个同时请求而apache本身 prefork工作模型就是基于select模型来完成的,所以限制了prefork模型最多接收进来的请求进来同时不能超过1024个,因此在一旦用户并发请求数(在线请求数)超过1024个,apache就不再提供服务了,所以说使用select 模型的apcahe的性能很差,至少说在用户请求量非常大的情况下,apache的prefork模型情况下是应付不来的。

基于select模式虽然实现了IO复用,也解决了多路调用的问题,但是个缺陷,多路复用本身的后半段仍是阻塞状态,只不过是阻塞在select而没有阻塞在IO调用上,由负责扫描多个IO 使得整个系统能够完成多路I/O了 但是多了一个处理机制性能在一定程度来讲,未必是上升,有可能还会下降,于是就有了第四种模型:event-driven


event-driven(基于事件驱动复用机制):扫描全是全局,而这种通知只是哪个完成通知哪个,对于被调用来讲,他的任何一个调用请求执行完成才会通知给调用者,而且没被处理完成不会被通知。

本身是通过事件函数主动发起通知的,比select的调用机制要强大很多,


event:进程发起请求之后,进程会发起"回调 函数"意味着向内核发送信息"要发起系统调用",内核会记录哪个进程发起的请求,于是进程处理其他请求,一旦第一段完成,内核通过毁掉函数向发起请求的进程发起通知,于是阻塞在第二阶段。虽然一个进程响应多个请求有缺陷:第二段仍然会阻塞,仍然会影响系统性能,复制的过程如果有新用户请求过来则不能接收


AIO:异步IO

异步IO缺陷:复制完成之后才会通知,为了增强AIO的性能研发了mmap

mmap:内存映射机制 内核将数据从磁盘装载进内核内存之后,不再复制,直接建立映射关系,进程访问的仍然是自己的内存空间,但是数据是来自于内核的。


基于IO模型实现的web架构:

(1)单进程模型

假如一次来5个请求,每个请求都产生一个网络IO,第一个用户请求进来,web通过io调用返回给用户,直到用户响应结束后第二个用户才能被处理。单进程模型是最简单的模型也可以理解为单线程阻塞模型

(2)多进程模型

每个用户请求到达主进程,请求到达之后 ,发现请求的是当前主机,这是则派发一个子进程来响应请求,以此类推,主进程只接受用户请求并为其派发子进程,而prefork机制是根据select函数来调用的

(进程次数切换过多的结果就是把大量的CPU资源都耗费在内核模式上,而且是白白浪费)

(3)worker模型

首先生成主进程来监听端口,从而生成多个工作子进程,每个子进程会生成多个线程来工作,请求到来时,主进程会负责从工作子进程中招一个线程来响应请求。

(4)prefork模型,上面提到了哦





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值