
标签(空格分隔): 多路复用
这个好
poll_wait 函数所做的工作是把当前进程添加到 wait 参数指定的等待列表(poll_table)中
如果当前不可读,那么在sys_poll->do_poll中当前进程就会睡眠在等待队列上,这个等待队列是由驱动程序提供的(就是poll_wait中传入的那个)。当可读的时候,驱动程序可能有一部分代码运行了(比如驱动的中断服务程序),那么在这部分代码中,就会唤醒等待队列上的进程,也就是之前睡眠的那个,当那个进程被唤醒后do_poll会再一次的调用驱动程序的poll函数,这个时候应用程序就知道是可读的了。
如果tv_sec和tv_usec都是0,那么就是超时时间为0,那么select就会立刻返回了。
如果timeout这里是个NULL,那么超时就未被启用,会一直阻塞在监视文件描述符的地方
(之前有一次直接填了个0,想着超时时间是0了应该立即返回啊,谁知道一直卡在那里,感觉跟填了个NULL一样,最后一想才知道,NULL在有的系统中不就是0么
所以,填0和填NULL是一个效果,会导致超时不启用)
select的精髓在于使用等待队列去监测并且探测底层主动向上层通知的消息
做的试验:标准的poll或者select,diver要满足这3点:
1,driver中一定要实现等待项

1.一定要在driver中实现poll函数,(poll返回真表示有数据,此时select返回一个大于0的值,poll显示无数据的时候,select返回为0)
同时将等待项加入到select维护的一个等待队列中
3,同时driver中一定要有唤醒机制,即数据准备好了以后,要有地方去唤醒,
当select工作的时候,分为3种情况:
1.select中的超时间为0,tv.tv_sec = 0;tv.tv_usec = 0;,不是直接在最后一个参数写0。此时表示无阻塞的去监控描述符。
此时select 会call一次各个被监控driver中的epoll函数去检查是否准备好数据,如果select在一个while中的话,select不会阻塞,会一直轮询执行,
这种方式,对于实现了poll而没有实现等待的driver,select每次调用poll,如果poll返回不为真(数据未准备好),select直接返回0,表示数据未监测到。epoll select 原理图
当driver数据准备好以后,是poll为真,select在某次call 到poll发现为真以后返回大于0的数,然后使用FD_ISSET()去检测是哪个fd有数据了再去读。
可以看出这种方式和driver被while(1)轮询检测的方式没有什么两样。就算driver实现了阻塞,数据未准备好的时候阻塞,select也是不会阻塞的,立马返回
所以不建议这样使用
2.select中的超时间为NULL。此时表示一直阻塞(睡眠)的去监控描述符。epoll select 原理图
![]()
此时,select不会主动去call driver中的poll函数,只有当底层数据准备好了,唤醒之前在poll中注册的等待项,同时使poll返回为真。此时select监测到有唤醒信号,
然后遍历一遍自己维护的等待队列,找到对应的poll,去call这个poll,然后再查返回值,如果返回为真,表示这个描述符有数据来了,然后select返回一个大于0 的值。
然后使用FD_ISSET()去检测是哪个fd有数据了再去读。
这种方式一定要在driver中实现等待,一定要有唤醒,否则,select探测不到。在driver中注册了等待项以后,不需要在read中阻塞(设置不设置都一样),但一定有个
地方去唤醒。这其实是select和poll真正的用法
只有当设备数据准备好了,才去通知上层从睡眠中醒来去收数据,这样子非常节省cpu
3.select中的设置超时时间,此时表示在这个时间内阻塞(睡眠)的去监控描述符,时间一到就不阻塞,会去call一次各个driver中的poll函数,看准备好了
这个和2很类似,在睡眠期间可以被driver唤醒然后再去call一遍所有driver 中的poll。区别就在于如果时间到了还没有人唤醒,就自己醒来,去call一遍poll看
各个driver有数据准备好没,如果没有,就继续睡
NOTE:while(1)中的select每调用一次,fd就应该使用FD_SET重新加入到监控描述符列表
有试验过,如果driver中不是实现poll和等待项,使用select依然可以探测到数据,不过这种方式就像while轮询,没有阻塞。并且默认的会导致select一直返回大于0的值
并且FD_ISSET()也返回一个真。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-84712-1.html
中国没有不好
恶意攻击诋毁用的吧
少读书