Linux_ select 多路复用
多路复用select
问题
当需要等待某个或多个设备(文件)可读或可写时,
如果使用循环不停地检测是否可读可写,则效率很低。解决办法:
使用select系统调用。select的用法
man 2 selectint select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
功能:阻塞readfds、writefds和exceptfds中的文件描述符,
直到其中任一个文件描述符达到对应的状态(可读、可写、或错误状态),
或者最久阻塞到指定的超时时间。文件描述符集fd_set
相关操作:FD_ZERO 清空集合
FD_CLR 把指定的文件描述符从集合中删除
FD_SET 把指定的文件描述符添加到集合中
FD_ISSET 检查指定的文件描述符是否在集合中时间类型struct timeval
见man 2 select
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};参数1:表示要监听的文件描述符个数。
如果为3,则监听0,1,2
一般取需要监听的文件描述符的最大值+1
参数5:超时时间,如果为NULL, 则表示不使用超时时间,即一直阻塞。返回值:
成功:返回状态发生变化的文件描述符总数
失败: 返回-1(中断、无效的文件描述符、select的参数1/参数5错误)注意:select返回后,文件描述符集中会发生变化,如果超时,则都清空
超时时间则可能发生变化。
所以,在循环监听中,重新select之前,要重新设置超时时间和文件描述符集select返回后,如果返回值>0, 则需要再次检测,所需要的文件描述符是否在对应的集合中!
实例
main1.c
循环监听用户的输入,一收到就打印输出。
直到用户输入exit“set_tx_power 30”
atoi(“30”) = 30
atoi(” 30”) = 30
atoi(a30”) = 0