Socket的总结,结合常见问题
介绍一下I/O模型
一个输入操作,包含:等待数据准备好,从内核向进程复制数据两个阶段
五大I/O模型
阻塞时I/O、非阻塞式I/O、I/O复用、信号驱动式I/O、异步I/O
介绍一下阻塞式I/O
应用进程被阻塞,直到数据从内核缓冲区复制到应用进程缓冲区中才返回
介绍一下非阻塞式I/O
应用进程执行系统调用之后,内核返回一个错误码。应用进程可以继续执行,但是需要不断的执行系统调用来获知 I/O 是否完成,这种方式称为轮询(polling)
阻塞式I/O与非阻塞式I/O的区别
阻塞式I/O发起后进程会被阻塞,非阻塞式I/O不会,但阻塞式I/O没有那么多的系统调用,CPU利用率高
介绍一下I/O复用
使用 select 或者 poll 等待数据,并且可以等待多个套接字中的任何一个变为可读。这一过程会被阻塞,当某一个套接字可读时返回,之后再使用 recvfrom 把数据从内核复制到进程中,它可以让单个进程具有处理多个 I/O 事件的能力
介绍一下信号驱动I/O
应用进程使用 sigaction 系统调用,内核立即返回,应用进程可以继续执行,也就是说等待数据阶段应用进程是非阻塞的。内核在数据到达时向应用进程发送 SIGIO 信号,应用进程收到之后在信号处理程序中调用 recvfrom 将数据从内核复制到应用进程中
介绍一下异步I/O
应用进程执行 aio_read 系统调用会立即返回,应用进程可以继续执行,不会被阻塞,内核会在所有操作完成之后向应用进程发送信号
异步I/O与信号驱动I/O的区别
异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O
介绍一下select
使用fd_set实现,大小为FD_SETSIZE,三种描述符类型readset、writeset、exceptset
timeout为超时参数
成功返回大于0,出错为-1,超时为0
介绍一下poll
与select类似,描述符为pollfd类型数组
select与poll的比较
select会修改描述符,poll不会
select有数量限制,poll没有
poll对描述符的重复利用比select高
select可移植性比poll高
介绍一下epoll
epoll_creat()创建句柄,声明监听的数目+1
epoll_ctl()用于添加/删除/修改描述符(维护在红黑树上)
epoll_wait()轮询I/O事件的发生
epoll不会产生select/poll的监听某描述符时另一线程关闭该描述符造成的不确定结果
介绍一下epoll的两种工作模式
LT模式:当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件,下次调用 epoll_wait() 会再次通知进程。是默认的一种模式,并且同时支持 Blocking 和 No-Blocking
ET模式:和 LT 模式不同的是,通知之后进程必须立即处理事件,下次再调用 epoll_wait() 时不会再得到事件到达的通知。很大程度上减少了 epoll 事件被重复触发的次数,因此效率要比 LT 模式高。只支持 No-Blocking,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死