杭州网站推广平台,秦皇岛网络优化排名,.我爱你 域名网站,重庆建一个网站大概要多少钱目录 1、阻塞IO模型2、非阻塞IO模型3、IO多路复用模型4、信号驱动IO模型5、异步IO模型总结 blockingIO - 阻塞IOnonblockingIO - 非阻塞IOIOmultiplexing - IO多路复用signaldrivenIO - 信号驱动IOasynchronousIO - 异步IO
5种模型的前4种模型为同步IO#xff0c;只有异步IO模… 目录 1、阻塞IO模型2、非阻塞IO模型3、IO多路复用模型4、信号驱动IO模型5、异步IO模型总结 blockingIO - 阻塞IOnonblockingIO - 非阻塞IOIOmultiplexing - IO多路复用signaldrivenIO - 信号驱动IOasynchronousIO - 异步IO
5种模型的前4种模型为同步IO只有异步IO模型是异步IO操作
首先我们知道对于一个网络输入操作通常包括两个不同阶段
第一阶段等待网络数据到达网卡→读取到内核缓冲区数据准备好
第二阶段从内核缓冲区复制数据到进程缓冲区复制数据了
这很显然是两个操作所以我们重点关注以下2点操作
A、等待数据读取到内核缓冲区数据准备
B、复制内核缓冲区数据到进程缓冲区数据复制
1、阻塞IO模型
进程发起IO系统调用后进程被阻塞转到内核空间处理整个IO处理完毕后返回进程。
调用者调用了某个函数等待这个函数返回期间什么也不做不停的去检查这个函数有没有返回必须等这个函数返回才能进行下一步动作。
即A阻塞B阻塞
举例
你准备去书店买书但老板不在留了电话
你打电话问老板有没有《三体》卖
老板查了一下说书店里没有《三体》我打个电话让供应商送货你等一下
然后你就一直在书店里等着不吃饭不睡觉进入A阶段等待数据陷入了IO阻塞
过了一段时间供应商把书送到书店
老板打电话给你书已经到了你有空吗等你有空我才当面把书交给你进入B阶段数据复制阻塞住了
交易完成
2、非阻塞IO模型
进程发起IO系统调用后如果内核缓冲区没有数据需要到IO设备中读取进程返回一个错误而不会被阻塞但会一直轮询内核缓冲区数据准备好了没。进程发起IO系统调用后如果内核缓冲区有数据内核就会把数据返回进程。
非阻塞等待每隔一段时间就去检测IO事件是否就绪。没有就绪就可以做其他事。非阻塞I/O执行系统调用总是立即返回不管时间是否已经发生若时间没有发生则返回-1此时可以根据errno区分这两种情况对于acceptrecv和send事件未发生时errno通常被设置成eagain。
即A不阻塞B阻塞
举例
你准备去书店买书但老板不在留了电话
你打电话问老板有没有《三体》卖
老板查了一下说书店里没有《三体》我打个电话让供应商送货你先回家去吧过几天再来问进入A阶段等待数据但非阻塞
想象你回到家该吃就吃该喝就喝隔了1周后才打电话问老板书到了没非阻塞继续做别的事情
但一般编程都会设置轮询IO即
实际你回到家循环不停地打电话给老板我的书到了没陷入事实上的轮询IO阻塞相当于死循环即使属于非阻塞模型
过了1个小时老板说书已经到了你有空吗等你有空我才当面把书交给你进入B阶段数据复制阻塞住了
交易完成
3、IO多路复用模型
多个进程的IO可以注册到一个复用器select上然后用一个进程调用该复用器select。 复用器select会监听所有注册进来的IO。如果复用器select所监听的IO在内核缓冲区都没有可读数据复用器select调用进程会被阻塞而当任一IO在内核缓冲区中有可数据时复用器select调用就会返回。之后复用器select通知注册进程来再次发起读取IO读取内核中准备好的数据。
linux用select/poll函数实现IO复用模型这两个函数也会使进程阻塞但是和阻塞IO所不同的是这两个函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检测。知道有数据可读或可写时才真正调用IO操作函数。
即A不阻塞B阻塞
举例
对于书店老板来说他对接的是多个客人。你张三李四都打电话给老板要买书
你买《三体》张三买《鲁迅》李四买《史记》然后最坏的情况3本书老板都没有
老板说我打个电话让供应商送货你们先别一直打电话书到了我再打电话让你们过来取
实际你张三李四挂了电话就去吃饭睡觉做自己的事了进入A阶段等待数据但非阻塞
老板一直等不到供应商来送货但自己需要一直等待着陷入事实上的select/poll/epoll阻塞
此时供应商送来一本书但老板不知道属于谁得遍历一边购书单发现是你的书
老板打电话给你书已经到了你有空吗等你有空我才当面把书交给你进入B阶段数据复制阻塞住了
交易完成
4、信号驱动IO模型
当进程发起一个IO操作会向内核注册一个信号处理函数 然后进程返回当内核数据就绪时会发送一个信号给进程进程便在信号处理函数中调用IO读取数据
linux用套接口进行信号驱动IO安装一个信号处理函数进程继续运行并不阻塞当IO时间就绪进程收到SIGIO信号。然后处理IO事件。
即A不阻塞B阻塞
举例
你准备去书店买书但老板不在留了电话
你打电话问老板有没有《三体》卖
老板查了一下说书店里没有《三体》
然后你说我给你留个收货地址。如果书到了你打电话给我我会让别人在这个地址接收你的书
然后你就回家去了该干嘛干嘛进入A阶段等待数据但留了回调函数非阻塞
老板打电话给你书已经到了让你的人准备好我才当面把书交给你的人进入B阶段数据复制阻塞住了
交易完成
5、异步IO模型
当进程发起一个IO操作进程立即返回但也不返回结果内核把整个IO处理完后会通知进程结果。如果IO操作成功则进程直接获取到数据。所谓的通知进程结果是指包含将数据从内核复制到应该进程的缓冲区完成后通知应用进程也就是说已经完成了A B 2个步骤了才通知请求进程此时请求进程直接获取到数据根本不会阻塞即所谓的异步。
linux中可以调用aio_read函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式然后立即返回当内核将数据拷贝到缓冲区后再通知应用程序。
即A不阻塞B不阻塞
你准备去书店买书但老板不在留了电话
你打电话问老板有没有《三体》卖
老板查了一下说书店里没有《三体》你留个地址书到了我会把书送到你家去
然后你就回家去了该干嘛干嘛进入A阶段等待数据非阻塞
老板接收到供应商的书把书放到你家楼下而此时你在家睡觉进入B阶段数据复制非阻塞
老板打电话给你书已经到了在你家楼下自己去拿吧
交易完成
总结
根据上面所说的IO操作的两个阶段可以把上面的I/O模型进行如下归类:
阻塞IO在两个阶段上面都是阻塞的A阶段阻塞B阶段还是阻塞 非阻塞IO在A不阻塞但陷入事实上的轮询IO阻塞B阶段还是阻塞的 IO复用A阶段不阻塞陷入事实上的select/poll/epoll阻塞B阶段还是阻塞的 信号IOA阶段不阻塞当信号通知程序数据准备完毕B阶段还是阻塞的 异步IOA阶段不阻塞B阶段不阻塞
现在我们可以看到前4种IO模型的B阶段数据复制阶段都是阻塞也就是按POSIX标准来说的同步IO最后1种异步IO模型才是按POSIX标准来说的异步IO。
同步一般指主动请求并等待I/O操作完毕的方式I/O操作未完成前会导致应用进程挂起
而异步是指用户进程触发IO操作以后便开始做自己的事情而当IO操作已经完成的时候会得到IO完成的通知异步的特点就是通知这可以使进程在数据读写时也不阻塞
阻塞或者非阻塞I/O主要是指I/O操作第一阶段的完成方式(进程访问的数据如果尚未就绪)即数据还未准备好的时候应用进程的表现
如果这里进程挂起则为阻塞I/O否则为非阻塞I/O主要是描述进程在数据未准备好时的状态根据进程等待数据时的状态来判断
阻塞和非阻塞是针对于进程在访问数据的时候根据IO操作的就绪状态来采取的不同方式
说白了就是一种读取或者写入操作函数的实现方式阻塞方式下读取或者写入函数将一直等待
而非阻塞方式下读取或者写入函数会立即返回一个状态值