关于select调用过程的一点理解

select、poll、epoll的介绍请参考:https://blog.csdn.net/zymill/article/details/79998593

epoll详解:https://www.cnblogs.com/lojunren/p/3856290.html

 

其中select实现中讲的select调用步骤,我的理解如下:

1.将设定好的fd_set从用户态拷贝到内核态。监听fd的操作只有内核才能完成,因而必须有这样一个过程。

2. fd_set里的每个fd中都有一个进程等待队列。当fd准备就绪的时候就会通知这个进程。如果想要fd通知调用select的进程,那么必须将该进程注册到fd的等待队列中。也就是说,只要调用select,就必须先遍历一遍依次注册进程。可以认为是初始化吧。

3. 第二步在向fd注册进程时,如果发现fd已就绪,那么就可以在遍历完所有的fd后,直接返回。如果一个都没有就绪,那么调用select的进程就会进入睡眠,直到有一个fd通知它的所有的等待队列中的进程(含调用select的进程),select再次遍历fd,查看有没有就绪的fd。

4.将就绪的fd_set从内核态复制到用户态。

关于epoll高效的原因:

  1. epoll_wait调用ep_poll,当rdlist为空(无就绪fd)时挂起当前进程,直到rdlist不空时进程才被唤醒。
  2. 文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。
  3. ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。
  4. ep_events_transfer函数将rdlist中的epitem拷贝到txlist中,并将rdlist清空。
  5. ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对用的poll方法。此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。 
  6. 使用事件回调机制来代替轮询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值