操作系统学习:IO多路复用

最基本的socket模型

我记得socket其实就是对应用层以下的部分进行打包,也就是传输层,网络层,网络发送层

每次使用的时候就创建一个socket,为其指定IP和端口,让这个socket可以被找到,然后启动listen监听

服务端监听后,调用accept()会去连接池拿已经握手成功的tcp连接

注意这里有两个socket,一个监听,一个接收发送数据

本质上socket也是一个文件,通过文件读写来实现接收发送数据,毕竟linux一切皆文件

多进程模型

每个客户端fork一个子进程来处理网络请求

这里其实还是一个socket,因为子进程fork父进程的时候同时会获取socket

坏处:

  1. 子进程不好好处理会变成僵尸进程,消耗系统资源
  2. 进程上下文开销太大,切换上下文需要保存栈,文件描述符,寄存器等东西

多线程模型

多进程开销太大,就换成线程来

维护一个线程池子,每次新连接建立,就把建立的socket放到队列里,然后从线程池里取一个来处理

缺点:需要多线程处理加锁

IO多路复用

多线程,多进程本质都是一个进程/线程处理一个socket

IO多路复用就是一个进程处理多个socket

select/poll

处理方法就是,操作系统把已经建立连接的socket的文件描述符,放到一个集合里,然后拷贝给内核态

内核态接收到网络请求,就标记这个socket,然后把整个集合传回用户态,用户态再遍历找到这个socket处理

都是线性结构,两次拷贝两次遍历都很消耗时间

epoll

epoll优化的地方是数据结构,不再使用集合,而是在内存里使用红黑树来维护建立连接的socket,使用链表来维护有请求的socket

边缘触发vs水平触发

边缘触发,就是第一次满足条件就通知,之后不再通知,所以也尽可能一次就读取完所有数据

水平触发,就是只要满足条件就不断通知

select/poll是水平触发

epoll是边缘触发,更高效


操作系统学习:IO多路复用
http://example.com/2024/07/01/操作系统学习:IO多路复用/
作者
WoodQ
发布于
2024年7月1日
许可协议