Unix 网络IO模型介绍
带着问题阅读
1、什么是同步异步、阻塞非阻塞
2、有几种IO模型,不同模型之间有什么区别
3、不同IO模型的应用场景都是什么
同步和异步、阻塞和非阻塞
同步和异步
广义上讲同步异步描述的是事件中发送方和接收方之间的关系。
- 当发送方必须依赖接收方的响应结果(无论正确与否)才能进行下一步操作,则两者间的关系是同步的。
- 当发送方不必依赖接收方的响应即可继续执行,则两者间的关系是异步的。在异步关系中,发送方可能根本不在意接收方的返回信息,也可能接收方通过事件、回调的形式来通知发送方结果。
即在同步关系中,发送方和接收方的步调是一致的,而异步关系中则没有必要。
快递员派送一件必须当面签收的贵重物品,快递员必须在客户签字后才能确认送达,快递员和客户的关系就是同步。
快递员派送普通物件,直接放到快递柜里,客户取出后系统自动确认送达,快递员和客户的关系就是异步。
阻塞和非阻塞
阻塞和非阻塞形容的是事件单个参与者的状态。
- 当参与者因为某些条件没有满足而无法执行下一步动作,只能原地等待,那么该参与者就陷入了阻塞。
假设有一条单行车道,有一天道路中央由于暴雨积水严重无法通过,那么经过这条路的车辆便陷入了阻塞状态。
四种组合
同步阻塞:发送方发起调用后,必须等待接收方的完成响应,且在此期间发送方不能执行任何动作。
顾客去银行柜台存钱,在柜员存入流程完成之前,顾客必须在柜台前等候流程结束。
同步非阻塞:发送方发起调用后,如接收方不能马上完成,可先返回给发送方一个未完成状态,发送方收到后可自行判断继续等待还是先执行其他动作再做轮询查看。
顾客去买奶茶,奶茶不能马上做好,就给了顾客一张单号。顾客可以在附近逛逛,每隔一会儿主动过来询问好了没有。
异步阻塞:发送方发起调用后无需等待接收方任何响应,但由于接收方的动作影响发送方的状态,发送方无法执行其他动作。(实践中通常没有该应用场景)
异步非阻塞:发送方发起调用后无需等待接收方任何响应,自由执行其他动作。
顾客去吃饭排队,小程序扫码以后就可以去别处逛。当排到该顾客时,小程序推送就餐消息给顾客。
UNIX IO模型
通常所说IO模型为网络IO模型,一个网络IO主要包含几个阶段:应用进程监听某个端口,等待数据从网络中到达网卡缓冲区,数据到达后CPU收到信号将数据转移到内核缓冲区,然后将数据从缓冲区复制到应用进程缓冲区。依据监听方式和数据复制方式的不同,UNIX IO主要分为5种IO模型。
阻塞IO
阻塞IO是最基础的IO模型,应用进程监听端口后就一直陷入阻塞状态,直到有数据到达。如下图所示,应用程序调用recvfrom后即陷入阻塞状态,直到CPU将数据拷贝到用户空间后,应用程序才能继续执行。
非阻塞IO
非阻塞IO允许应用程序调用recvfrom时立即返回,在数据没有就绪时,返回状态为EWOULDBLOCK,这时应用程序可继续执行,但需要不断发起轮询(polling)判断数据是否就绪。
非阻塞IO仅针对数据未就绪时是非阻塞的,在数据拷贝过程还是阻塞的。
IO多路复用
通过使用select/poll/epoll,应用进程可以同时等待多个设备的数据状态。应用程序在发起select/poll/epoll调用时会进入阻塞状态,但当其监听的任一个文件描述符数据就绪即可返回,应用程序即可对对应描述符发起recvfrom调用,拷贝应用数据。
IO多路复用带来的好处:
在上述的阻塞和非阻塞IO,如果要对多个描述符进行监听,则需要同时开启多个进程/线程。
通过select/poll/epoll可以使单个进程/线程具备监听多个连接的能力。
只要当IO事件发生时处理相应描述符即可,因此也称为事件驱动IO。
信号驱动IO
应用程序通过为SIGIO信号注册一个信号关联函数监听文件描述符,调用注册后应用程序可立即返回继续执行。当描述符数据就绪时,通过产生SIGIO信号发起对应用程序信号关联函数的调用,应用程序可通过recvfrom进行数据拷贝。
异步IO
异步IO模式下,应用程序触发系统调用后可立即返回,内核在数据拷贝完成后再对应用程序发出信号,触发应用程序逻辑。
异步IO与信号驱动IO的区别是:
- 信号驱动IO产生信号后,应用程序仍然需要阻塞读取数据到应用程序空间。
- 异步IO数据拷贝的过程也是由CPU进行的,直到拷贝完成才通知应用程序,做到全程非阻塞。
模型比较
通过前面的描述我们可以看出,前四种IO模型只有在等待数据阶段有区别,在拷贝数据时都会进入阻塞状态。而异步IO在应用程序的整个阶段都是非阻塞的。前四种IO都属于同步IO,最后一种属于异步IO。
POSIX把同步IO操作定义为导致进程阻塞直到IO完成的操作,反之则是异步IO。
select/poll/epoll
select
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。
select的缺点是
- select对于单个进程能够见识的文件描述符数量存在限制,32位环境为1024,64位为2048。
- select返回后仅直到有IO事件产生,具体到哪个描述符只能进行O(n)级别的轮询。
poll
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现,同时poll没有最大数量限制。
epoll
int epoll_create(int size);//创建一个epoll的句柄epfd,size用来告诉内核这个监听的数目一共有多大
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);//对指定fd添加删除监听事件
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);//等待句柄上的事件
epoll操作需要三个函数才完成创建,epoll可以直接返回哪些描述符产生了事件,因此复杂度时O(1)的。
epoll有两种工作方式:
- LT(level trigger)模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll_wait时,会再次响应应用程序并通知此事件。
- ET(edge trigger)模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件。
为什么要有两种模式:
如果采用LT模式的话,系统中一旦有大量你不需要读写的就绪文件描述符,它们每次调用epoll_wait都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率。而采用ET模式的话,当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你。
参考
Unix 网络IO模型介绍的更多相关文章
- unix网络io模型
阻塞I/O(bloking I/O) 阻塞IO的特点就是在IO执行的两个阶段(recvfrom和数据从内核空间转移到用户空间)都被block了 非阻塞I/O(non-bloking I/O) 非阻 ...
- python网络编程——网络IO模型
1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-bl ...
- Python socket编程之IO模型介绍(多路复用*)
1.I/O基础知识 1.1 什么是文件描述符? 在网络中,一个socket对象就是1个文件描述符,在文件中,1个文件句柄(即file对象)就是1个文件描述符.其实可以理解为就是一个“指针”或“句柄”, ...
- 5种网络IO模型
5种网络IO模型(有图,很清楚) 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到 ...
- python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
- {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块
python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...
- Socket-IO 系列(一)Linux 网络 IO 模型
Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...
- (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...
- python全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
随机推荐
- 腾讯云TKE-基于 Cilium 统一混合云容器网络(下)
前言 在 腾讯云TKE - 基于 Cilium 统一混合云容器网络(上) 中,我们介绍 TKE 混合云的跨平面网络互通方案和 TKE 混合云 Overlay 网络方案.公有云 TKE 集群添加第三方 ...
- 单片机引脚扩展芯片74HC595手工分解实验
我们先来看下效果 74HC595是常用的串转并芯片,支持芯片级联实现少量IO口控制多个IO口输出功能 14脚:DS,串行数据输入引脚 13脚:OE, 输出使能控制脚,它是低电才使能输出,所以接GND ...
- frp+nginx内网穿透
frp+nginx内网穿透 背景:自己有台内网Linux主机,希望被外网访问(ssh.http.https): 准备工作 内网Linux主机-c,可以访问c主机和外网的主机-s(windows/lin ...
- 实现opcache加速php7.X
一.环境准备 操作系统:Centos8.3.2011 软件:PHP7.2.24 二.安装过程 1.安装软件 [20:03:29 root@centos8 src]#dnf -y install php ...
- Innodb中有哪些锁?
0.前言 上一篇从MySQL层面上了解锁,那么这篇我们从存储引擎上来了解, 以MySQL默认存储引擎Innodb来说,看看有哪些锁?(MySQL版本为8) 1.Shared and Exclusive ...
- 用java实现斐波那契数列
斐波那契数列源于数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入的计算问题.假设某种兔子兔子,出生第一个月变成大兔子,大兔子再过一个月能生下一对小兔子,且一年 ...
- Windows10:虚拟机开机导致win10黑屏、蓝屏
管理员身份打开cmd(命令提示符) 执行如下5个命令 netsh winsock reset net stop VMAuthdService net start VMAuthdService net ...
- Quartz:Quartz任务异常处理方式
Quartz提供了二种解决方法 1 立即重新执行任务 2 立即停止所有相关这个任务的触发器 解决的方式是:在你的程序出错时,用Quartz提供的JobExecutionException类相关方法就能 ...
- 其他:IDEA插件无法安装——网络代理设置
1.网络代理设置 IDEA配置代理,是在File-> Setting-> plugins中设置 查看自己主机的IP地址 文章转载至:https://www.jianshu.com/p/62 ...
- Hibernate框架(三)框架中的关系映射
在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...