事件驱动模型与异步

传动的编程是代码块的函数串并联型
如果下面的功能用传统方法去做:
那么应该怎样设计:
1.一直监听鼠标点击
2.if 鼠标点击:
做点什么

这样,如果鼠标不点击,CPU一直就被占用,如果下面有什么其他动作则都不能做

事件驱动:
在这里插入图片描述

事件驱动的好处:
增加了CPU资源利用率

IO模型前戏准备

几个概念:
1 用户空间与内核空间:
(4G)用户的内存(后3G)没法访问操作系统的内存(前1G)

在这里插入图片描述

2 进程切换
大量的进程切换是一种对资源极度消耗的情况 不利

3 进程的阻塞
( accept recv )
这个动作是谁来发生的?----进程本身
进程拿着CPU权限在走 阻塞时进程将CPU交出去,阻塞结束 CPU再重新被获取

4 文件描述符(形式上是一个非负整数)
在这里插入图片描述
在这里插入图片描述
其实他是一个索引值,操作系统内核里维护着一张系统文件表
在这里插入图片描述
缓存I/O
socket一收一发

原来你也许会以为client发送的hallo直接存入用户态
其实 真正的过程是:
Client_hallo---->server 内核区---->server用户区
可是为什么要经过内核区?
原因:数据由物理层用网卡来接收 硬件接受的数据只能由操作系统去拿,只有他有这个权限

(他会拷贝一份数据并放入内存,这个过程也非常消耗资源)

五种IO模型
在这里插入图片描述
还有一个知识 数据拷贝文件描述符过程
例如:
accept() 接受(addr,conn)client端的socket 对象 就是fd

1 等待数据准备
2 数据进入内核空间 将数据从内核态拷贝到进程中
在这里插入图片描述
2 阻塞IO
之前学过的都是阻塞IO 比如 listen()就是阻塞IO
用setblocking()设置为非阻塞

在这里插入图片描述
可以创建 阻塞状态的动作都可以开启recivefrom进入上图那个圈
一直到kernel的数据准备完毕才会进行拷贝,返回结果给application,用户进程才能解除block,重新运行

(这个过程处于一个阻塞状态,效率比较低 )

3 非阻塞IO
解决了阻塞IO的低效率
在这里插入图片描述
有没有数据都一直往下走
application反复的轮询问
小虎变聪明了 没有回复的话就去干一会儿活再来问233

第二个阶段(取票)还是笨 只能阻塞着等…
弊端:(1)多次询问,(2)数据不能及时拿到 (问了一次 没有及时得到回复 干了很长时间后才能再次问 )

在这里插入图片描述
在这里插入图片描述
IO多路复用(思想就是上面的事件驱动模型)
(强大的AJAX的底层)
在这里插入图片描述

select/epoll与recv 两者都可以开启阻塞
不同点:
select不直接返回数据 而返回数据可读的信号 后面还得加上一次recv

select的强大之处是
waiting for one of possibly many sockets to become readable
可监听多个socket对象

NEW BEE 的来了---------异步IO
比非阻塞还牛必 没有一点阻塞 (只要有一点阻塞 那就不叫异步)

在这里插入图片描述

数据准备好了直接通知 并且交给进程接收去处理 这直接把进程供奉为皇上级别!!!

epoll只能算伪异步 ,还只是个同步

阻塞 IO多路模型
非阻塞 异步IO

取票的时间再短也得花时间!!!

不同的用户享受不同的内核数据准备的服务:
情景:你去买卤菜

阻塞:买卤菜的时候老老实实地等

非阻塞:你和老板很熟,老板给你权限 让你可以先去忙别的,过会儿再来问菜有没有准备好,如果在你干活的间隔里菜已经准备好,那么必然会出现时间浪费,而且最重要的是最后你还得花时间去哪儿等着去拿菜

异步IO:你直接给小老板打了个电话,让他做好卤菜后之直接给你处理好送过来能直接吃

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43604927/article/details/89788827