欢迎来到天天文库
浏览记录
ID:14253833
大小:28.00 KB
页数:4页
时间:2018-07-27
《linux中select系统调用》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、select系统调用是用来让我们的程序监视多个文件描述符(filedescrīptor)的状态变化的。程序会停在select这里等待,直到被监视的文件描述符有某一个或多个发生了状态改变。select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组, 每一个数组元素都能与一打开的文件描述符(不管是Socket描述符,还是其他 文件或命名管道或设备描述符)建立联系,建立联系的工作由程序员完成, 当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执 行了s
2、elect()的进程哪一Socket或文件可读,select函数原型如下:intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);函数的最后一个参数timeout显然是一个超时时间值,其类型是structtimeval*,即一个structtimeval结构的变量的指针,所以我们在程序里要申明一个structtimevaltv;然后把变量tv的地址&tv传递给select函数。s
3、tructtimeval结构如下:structtimeval{long tv_sec; /*seconds*/long tv_usec; /*microseconds}第2、3、4三个参数的类型是一样的: fd_set*,即我们在程序里要申明几个fd_set类型的变量,比如定义了rfds,wfds,efds。另外关于fd_set类型的变量,还有一组标准的宏定义来处理此类变量:FD_ZERO(fd_set*fdset):清空fdset与所有文件描述符的联系。FD_SET(intfd,fd_set*fd
4、set):建立文件描述符fd与fdset的联系。FD_CLR(intfd,fd_set*fdset):清除文件描述符fd与fdset的联系。FD_ISSET(intfd,fd_set*fdset):检查fd_set联系的文件描述符fd是否可读写,>0表示可读写。(关于fd_set及相关宏的定义见/usr/include/sys/types.h)定义的这三个参数都是描述符的集合,第一个rfds是用来保存这样的描述符的:当描述符的状态变成可读的时系统就会告诉select函数返回,第二个wfds是指有描述
5、符状态变成可写的时系统就会告诉select函数返回,第三个参数efds是特殊情况,即描述符上有特殊情况发生时系统会告诉select函数返回。下面以一个输入为例来说明:intfd1,fd2; /* 在定义两个描述符*/fd1=socket(...); /* 创建socket连接*/fd2=open(“/dev/tyS0”,O_RDWR);/* 打开一个串口*/FD_ZERO(&rfds); /* 用select函数之前先把集合清零 */FD_SET(fd1,&rfds); /* 分别把2个描述符加入读
6、监视集合里去 */FD_SET(fd2,&rfds);intmaxfd=0;maxfd=(fd1>fd2)?(fd1+1):(fd2+1); /* 注意是最大值还要加1*/ret=select(maxfd,&rfds,NULL,NULL,&tv);/*然后调用select函数*/这样就可以使用一个开关语句(switch语句)来判断到底是哪一个输入源在输入数据。具体判断如下:switch(ret){case-1:perror("select");/* 这说明select函数出错 */case0:pri
7、ntf("超时/n");/* 说明在设定的时间内,socket的状态没有发生变化 */default:if(FD_ISSET(fd1,&rfds)) 处理函数1();/*socket有数据来*/if(FD_ISSET(fd2,&rfds)) 处理函数2();/*ttyS0有数据来*/}注:fgets()函数只有遇到''时fd==0才会“readyforread”
此文档下载收益归作者所有