IO 模型

文章详细介绍了同步/异步、阻塞/非阻塞的概念,并探讨了Reactor和Proactor两种IO模型。重点讲解了epoll在Linux中的应用,包括epoll_create、epoll_ctl和epoll_wait的功能,以及ET(EdgeTriggered)和LT(LevelTriggered)两种工作模式。epoll作为高效的IO多路复用机制,尤其适用于高并发的网络编程场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO 模型

同步/异步:用户线程和内核的交互方式。
阻塞/非阻塞:用户线程调用内核IO操作的方式。

概念描述
同步用户线程发送IO请求后,需要等待或者轮询内核IO操作完成后,才能继续执行。
异步用户线程发送IO请求后,仍继续执行。当内核IO操作完成后会通知用户线程,或调用用户线程注册的回调函数。
阻塞IO操作完成后,才会返回用户空间。
非阻塞IO操作被调用后立即返回用户状态值。

Reactor 模型

Reactor 模型

Proactor 模型

Proactor 模型

文件描述符(fd)

是 File descriptor 的缩写,中文名叫做:文件描述符。文件描述符是一个非负整数,本质上是一个索引值。
file_struct 本质上是用来管理所有打开的文件的,内部的核心是由一个静态数组和动态数组管理结构实现。
struct file 是属于系统级别的结构,换句话说是可以共享与多个不同的进程。
父进程打开了文件,后面 fork 出一个子进程。这种情况就会出现共享 file 的场景。

系统调用

通过红黑树和双链表数据结构,并结合回调机制,造就了epoll的高效。

  • epollcreate 负责创建一个池子,一个监控和管理句柄 fd 的池子;
  • epollctl 负责管理这个池子里的 fd 增、删、改(红黑树);
  • epollwait 就是负责打盹的,让出 CPU 调度,但是只要有“事”,立马会从这里唤醒;

poll接口

poll是Linux的事件轮询机制函数,每个进程都可以管理一个pollfd队列,由poll函数进行事件注册和查询。

通过 poll 机制让上层能直接告诉底层,我这个 fd 一旦读写就绪了,请底层硬件(比如网卡)回调的时候自动把这个 fd 相关的结构体放到指定队列中,并且唤醒操作系统。
中断一般拆分成两部分:硬中断和软中断。poll 函数就是把这个软中断回来的路上再加点料,只要读写事件触发的时候,就会立马通知到上层,采用这种事件通知的形式就能把浪费的时间窗就完全消失了。
就绪队列就是一个最简单的双指针链表

  • ext2,ext4,xfs 等这种真正的文件系统的 fd ,无法使用 epoll 管理;
  • socket fd,eventfd,timerfd 这些实现了 poll 调用的可以放到 epoll 池进行管理;

epoll的工作模式

  • ET(EdgeTriggered):高速工作模式,只支持no_block(非阻塞模式)。在此模式下,当描述符从未就绪变为就绪时,内核通过epoll告知。然后它会假设用户知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到某些操作导致那个文件描述符不再为就绪状态了。(触发模式只在数据就绪时通知一次,若数据没有读完,下一次不会通知,直到有新的就绪数据)

  • LT(LevelTriggered):缺省工作方式,支持blocksocket和no_blocksocket。在LT模式下内核会告知一个文件描述符是否就绪了,然后可以对这个就绪的fd进行IO操作。如果不作任何操作,内核还是会继续通知!若数据没有读完,内核也会继续通知,直至设备数据为空为止!

参考

epoll
golang 利用 epoll
网络模型
Reactor & Proactor
Reactor & Proactor
ET&LT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值