用户空间和内核空间

为了避免用户应用导致冲突甚至内核崩溃,用户应用与内核是分离的:
进程的寻址空间会划分为两部分:内核空间、用户空间。

用户空间只能执行受限的命令(Ring3),而且不能直接调用系统资源,必须通过内核提供的接口进行访问。
内核空间可以执行特权命令(Ring0),调用一切系统资源。

写数据:把用户缓冲区数据拷贝到内核缓冲区,然后写入设备
读数据:从设备读取到内核缓冲区,再拷贝到用户缓冲区

五种IO模型

几种IO网络模型的差异主要在:(1)等待数据就绪(2)数据拷贝

1.阻塞IO(Blocking IO)

用户进程在两个状态下都是阻塞的。阻塞等待,不占用CPU宝贵的时间片。

2.非阻塞IO(Nonblocking IO)

第一阶段不阻塞,第二阶段阻塞。非阻塞会让CPU空转,占用CPU系统资源。


3.IO多路复用(IO Multiplexing)

文件描述符(File Descriptor):简称FD,是一个从0开始递增的无符号整数,用来关联Linux中的一个文件,在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)。

多路复用是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。


4.信号驱动IO(signal Driven IO)

与内核建立SIGIO的信号关联并设置回调,当内核有FD就绪时,会发出SIGIO信号通知用户,期间用户应用可以执行其它业务,无需阻塞等待

缺点

(1)当有大量IO操作时,信号较多,SIGIO处理函数不能及时处理可能导致信号队列溢出
(2)内核空间与用户空间的频繁信号交互性能较低。


5.异步IO(Asynchronous IO)

整个过程都是非阻塞的,用户进程调用完异步API后就可以去做其他事情,内核等待数据就绪并拷贝到用户空间后才会递交信号,通知用户进程。用户进程在两个阶段都是非阻塞状态。

缺点:并发量很大的时候会创建太多FD;实现比较复杂。

实现I/O多路复用的几种机制

1.select

缺点:

需要将fd_set(图中黑框)从用户空间拷贝到内核空间,select结束还要再次拷贝回用户空间。

select无法得知具体是哪个fd就绪,需要遍历整个fd_set。

fd_set监听的fd数量不能超过1024,保存在位图里。

2.poll

IO流程:

(1)创建poolfd数组,向其中添加关注的fd信息,数组大小自定义

(2)调用poll函数,将pollfd数组拷贝到内核空间,转链表存储,无上限

(3)内核遍历fd,判断是否就绪

(4)数据就绪或超时后,拷贝pollfd数组到用户空间,返回就绪fd数量n

(5)数组进程判断n是否大于0

(6)大于0则遍历pollfd数组,找到就绪额fd

与select区别

select模式中fd_set大小固定1024,而pollfd在内核中采用链表,理论上无上限

poll模式的缺点

需要遍历链表的所有FD,如果监听较多,性能会下降

3.epoll

epoll模式中如何解决select和poll中的问题的?

基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高,性能不会随着监听的FD数量增多而下降。

每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传任何参数,无需重复拷贝FD到内核空间。

内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有FD就知道就绪的FD是谁。

事件通知机制
1.水平触发(level-triggered,LT)

当FD有数据可读时,会重复通知多次,直至数据处理完成,是Epoll的默认模式。

2.边缘触发(edge-triggered,ET)

当FD有数据可读时,只会被通知一次,不管数据是否处理完成。

惊群问题

当多个进程或线程同时监听同一个epoll实例时,如果有一个新的连接到来,内核会唤醒所有等待在该epoll实例上的进程或线程,但实际上只有一个进程或线程能成功处理该连接,其他被唤醒的进程或线程做了无效的操作,导致系统资源浪费和性能下降,在LT时会触发。

总结:select用int存fd,poll用链表,epoll用红黑树。

参考:

【黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目】 https://www.bilibili.com/video/BV1cr4y1671t/?p=160&share_source=copy_web&vd_source=554f6cfaea00d504c732eb9b35cd6e8b

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐