//----------------------------------------------------
//AUTHOR: lanyang123456
//DATE: 2014-10-10
//----------------------------------------------------
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
在每次调用 select() 函数前,必须重新初始化 readfds, writefds 和 errorfds 参数。
select()使用时需要注意:
(1)返回值:
-1:出错
0 :超时(设置的timeout 超时)
> 0:有数据到来,可查看监听的readset、 writeset、exceptionset;
(2)最后一个参数
为NULL:select一直阻塞,直到有fd数据到来;
不为NULL:若有fd数据到来,则立即返回;否则,阻塞到指定时间超时才返回;
并且每次调用select前都要重新设置;
其中,timeout.tv_sec=0; timeout.tv_usec=0; 时,立即返回;
事件到来,fd有数据,对相应的fd读或写后,监听的相应位才被清除;
/* select usage read from keyboard. */ #include <sys/time.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <assert.h> #include <errno.h> int main () { int keybd_fd; int ret, i; char c; fd_set readfd; struct timeval timeout; keybd_fd = open("/dev/tty",O_RDONLY | O_NONBLOCK); assert(keybd_fd > 0); while (1) { /*每次调用select前,都要重置监听的描述符*/ FD_ZERO(&readfd); FD_SET(keybd_fd, &readfd); /*超时时间发挥一次作用,每次循环需要重置超时时间*/ timeout.tv_sec = 5; timeout.tv_usec = 0; ///监控函数 //ret = select(keybd_fd + 1, &readfd, NULL, NULL, NULL);//有数据时才返回 ret = select(keybd_fd + 1, &readfd, NULL, NULL, &timeout); if(ret == -1) { //错误情况 if (errno == EINTR) {//signal interrupt continue; } else { perror("select error"); } } else if(ret) { //返回值大于0 有数据到来 if(FD_ISSET(keybd_fd, &readfd)) { i = read(keybd_fd, &c, 1); if('\n' == c) continue; printf("input is %c\n", c); if ('q' == c) break; } } else //ret 为0,超时情况 { printf("time out\n"); //close(keybd_fd);//产生异常,查看结果 } //printf(" event clear only if read or write fd\n"); } }
参考linux man page、CSDN收藏以及:
http://www.groad.net/bbs/thread-1064-1-1.html
http://blog.csdn.net/microtong/article/details/4989902
http://blog.csdn.net/klarclm/article/details/8825930