IO多路复用的原理
IO多路复用的四个关键词:监控者、内核态、用户态、文件句柄。
IO多路复用的五个关键问题(步骤):
- 1.监控者如何将文件句柄从用户态传递到内核态。
- 2.内核如何判断文件句柄的读写状态
- 3.内核如何通知监控者文件句柄可读可写
- 4.监控着如何找到可读写的文件句柄并通知应用态的应用程序
不同的多路复用接口都是基于对这四个问题的不同解答实现的。 - 5.继续循环时,监控者怎么实现上面的流程
select的原理
针对这五个问题,select给出的解答是:
- 1.select设置三个文件描述符集,并将他们全部拷贝到内核中。fd数量最大为1024。
- 2.内核根据文件描述符的缓冲区来判断可读写状态
- 3.内核自己实现。
- 4.select遍历所有的文件描述符集合,通知用户可读写的fd数量,并将所有的文件描述符拷贝到用户空间。应用程序用FD_ISSET来检测可读写的描述符。
- 5.再次重复上面的流程。
epoll的原理
epoll使用的五个步骤:
- 1.epoll_init 会在内核中开辟一个专门的高速缓冲区,并在缓冲区上建立一个就绪链表和红黑树。红黑树用来存储监控的文件句柄。就绪链表用来存储可读写的文件句柄。
- 2.epoll_ctl用来删除或者添加文件句柄。添加的时候,epoll会把文件句柄放到红黑树上,同时注册一个回掉函数。这个回掉函数会把文件句柄拷贝到就绪列表中。删除的时候则把文件句柄从红黑树中删除即可。
- epoll_wait则监控就绪链表。一旦有时间发生,则返回用户态进程。
针对这五个问题,epoll给出的解答是: - 1.epoll将所有的文件句柄拷贝到内核的红黑树上
- 2.内核通过检测fd缓冲区来判断fd的读写状态
- 3.内核通过回调函数将可读写的文件句柄拷贝到就绪链表中
- 4.epoll_wait将就绪链表(少量)的句柄拷贝到用户空间,并返回到用户态。
- 5.内核没有修改文件句柄的位,可以一直重复监控,直到用epoll_del删除,无需重复上述过程。
epoll高效的两个原因
- 1.epoll只需要在add时将文件句柄拷贝到内核态,select每次调用后都要将所有的文件句柄拷贝到内核态,毫无疑问效率更低。(减少用户态跟内核态fd的拷贝)
- 2.事件发生时,select要遍历所有的文件描述符。epoll则不需要。(避免fd的线性遍历)
网友评论