1、Linux的五种I/0模型
1.1、阻塞I/O
进程会一直阻塞,直到数据拷贝完成
1.2 IO复用
select和epoll;对一个socket,两次调用,两次返回,比阻塞IO并没有什么优越性; 关键是能实现同时对多个socket进行处理。
1.2.1 IO复用
- select 读相关 写相关 和异常相关分开处理。最大限制1024
- poll 把三个和三为一,超过1024性能也持续下降。全部轮询一遍。
- epoll 把系统调用拆成3个。epoll_create创建文件描述符。epoll_ctl 类似于register 还支持事件增加删除修改。epoll_wait类似于select,等待看看有没有事件
1.3 非阻塞式IO
非阻塞IO通过进程反复调用IO函数(多次系统调用,并马上返回);在数据拷贝的过程中,进程是阻塞的
1.4 信号驱动IO
套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。 当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。
1.5 异步IO模型
当一个异步过程调用发出后,调用者不能立刻得到结果。 实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。
1.6 5个IO模型比较
2、Linux代码结构看网络通信
- CPU怎么知道网卡接受了数据-中断
- 到进程A read 的时候 然后就把进程A放到Socket 的等待队列当中。不会给A分配CPU时间片,有数据来以后A进程唤醒吃时间片
-
唤醒A进程,重新加入到操作系统的工作队列里,
-
操作系统怎么知道数据是到哪个进程去?一i那位端口号。
-
如果我要监视很多socket,用socket列表就好了。select慢的原因就是,我知道有数据来了,但不知道是哪个socket,我要都轮询一遍。调用一次select就用户态到内核态。
-
数据到了接受缓冲区
-
epoll的设计思路
- 用户态传递到内核态只要一次 epoll_create
- epoll_wait只返回有数据产生的socket
3、epoll高效原理和底层机制
- 收到数据的socket,rdlist也就是
就绪列表
(双向列表)会添加socket的引用
- 当进程A运行到了epoll_wait。网络数据来了之后,rdlist加了收到数据的socket,在唤醒eventpoll中
等待队列
的进程A。数据来了,你赶紧到rdlist里找。就不用全部轮询了。socket用红黑树管理。rdlist用的双向链表。handler中也用的epoll