IO Model
IO模型归纳
我们暂时只以网络IO为例子; 我们先从硬件层面进行流程分析:
1. 硬件层面
网卡
网卡等于一种可以接收外面数据流的一种设备;
- 网卡会先从网线处(或者无线)接收里面的数据
- 以某种方式写入到内存中
其中涉及DMA,IO通路选择等硬件问题,我们暂时忽略
CPU
接着,我们都知道一般操作系统针对一些比较紧急的操作会进行中断(软,硬),当网卡来数据的时候,明显就是比较紧急的事情(如果忽略不管,就会造成内存爆炸或者数据丢失);
所以,数据从网卡接收到,会立即发送一个信号到CPU,网卡的中断程序就会被调用去处理数据;
操作系统调度
2. 模型选择
同步
- 阻塞:
只能有一个I/O操作;
- 非阻塞:
指的是 可以同时阻塞多个I/O操作,所以看做是非阻塞的
select:
-
优点:实现简单,只用单线程执行,占用资源少,不消耗过多CPU,也可以为多客户端提供服务;
-
缺点:每次调用都都要将fd_set从用户态copy到内核态,消耗过大; 每次调用select都要进行多次轮询; 可以检测到fd数量有限,默认是1024; 因为是
水平触发
,如果没有完成对一个就绪fd进行IO,下次select也会将这些fd通知到进程(只能算的是特点吧); -
可以看到select就是将事件的探测和响应放在一起,一旦响应过大,就会造成问题;
poll
与select区别不大,相同的是
- 创建fd_set,设置关注事件
- 调用poll(),等待事件发生;
区别:
- select要为读、写、异常都分别设置fd_set, poll只需要为fd设置一个即可
- poll由链表实现,所以无最大值
缺点: 同select一样,用户态到内核态的copy; 水平触发;
epoll
将fd交给了内核,一旦事件发生,内核负责通知;
其支持水平触发
和边缘触发
,还有多个函数epoll_create
,epoll_wait
,epoll_ctl
分别为创建epoll句柄,等待事件发生,注册要监听的事件;
优点:
- 无最大并发连接数目限制
- 效率提升,只有活跃的fd才会callback
- 内存是由一块用户态和内核态通过
mmap()
共享内存,避免频繁copy,保证了整个过程只会copy一次;
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!