select模型旨在解决通过频繁调用非阻塞读写函数来轮询监听串口的各种不足。select调用允许用户把进程本身挂起来,同时使系统内核监听所要求的一组文件描述符的任何活动。只要确认在任何被监控的文件描述符上出现活动,select调用将返回指示该设备文件已经准备好的信息。这样就使进程能相对实时地监测到串口设备上随机的变化,而不必由进程本身去探测输入数据是否准备好。
函数原型:
int select(int n,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,struct timeval*timeout);
n:文件描述符集合中最大值再加1
readfds:可读文件描述符集合,当文件描述符的状态变成可读的时候系统就会告诉select函数返回
writefds:可写文件描述符集合,当文件描述符状态变成可写时系统会要求select函数返回
exceptfds:用于异常控制
timeout:超时时间(NULL:将select置于阻塞状态,文件描述符有变化才返回;0:立即返回;大于0;设置超时返回时间,超时时间内有事件发生则返回,若超时则返回)
FD_ZERO(&set); /*将set清零使集合中不含任何fd*/
FD_SET(fd, &set); /*将fd加入set集合*/
FD_CLR(fd, &set); /*将fd从set集合中清除*/
FD_ISSET(fd, &set); /*在调用select()函数后,用FD_ISSET来检测fd在fdset集合中的状态是否变化返回整型,当检测到fd状态发生变化时返回真,否则,返回假(0)*/
|
#include
<stdio.h> #include
<sys/select.h> #include
<unistd.h> int main( int argc,
char **argv) {
fd_set
fdset; FD_ZERO
(&fdset); /*清空集合中所有的元素*/ FD_SET(STDOUT_FILENO,&fdset); /*设置stdout,使集合中包含stdout*/ if (FD_ISSET(STDOUT_FILENO,&fdset)!=0) /*测试stdout是否包含在集合中*/ printf ( "stdout
has been set\n" ); else printf ( "stdout
has not been set\n" ); FD_CLR(STDOUT_FILENO,&fdset); /*从位向量中清除stdout*/ if (FD_ISSET(STDOUT_FILENO,&fdset)!=0) /*再次测试*/ printf ( "stdout
has been set\n" ); else printf ( "stdout
has not been set\n" ); return 0; } |