原创 linux设备驱动学习笔记5(续)-------select函数的学习

2009-11-25 10:21 2847 7 8 分类: MCU/ 嵌入式

select系统调用是用来让我们的程序监视多个文件描述符(file descrīptor)的状态变化的。程序会停在select这里等待,直到被监视的文件描述符有某一个或多个发生了状态改变。select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组, 每一个数组元素都能与一打开的文件描述符(不管是Socket描述符,还是其他 文件或命名管道或设备描述符)建立联系,建立联系的工作由程序员完成, 当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执 行了select()的进程哪一Socket或文件可读,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


select函数原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);


函数的最后一个参数timeout显然是一个超时时间值,其类型是struct timeval *,即一个struct timeval结构的变量的指针,所以我们在程序里要申明一个struct timeval tv;然后把变量tv的地址&tv传递给select函数。struct timeval结构如下:


struct timeval {
long   tv_sec;     /* seconds */
long   tv_usec;    /* microseconds


}


234三个参数的类型是一样的: fd_set *,即我们在程序里要申明几个fd_set类型的变量,比如定义了rfds, wfds, efds


另外关于fd_set类型的变量,还有一组标准的宏定义来处理此类变量:


FD_ZERO(fd_set *fdset):清空fdset与所有文件描述符的联系。


FD_SET(int fd, fd_set *fdset):建立文件描述符fdfdset的联系。


FD_CLR(int fd, fd_set *fdset):清除文件描述符fdfdset的联系。


FD_ISSET(int fd, fd_set *fdset):检查fd_set联系的文件描述符fd是否可读写,>0表示可读写。


(关于fd_set及相关宏的定义见/usr/include/sys/types.h定义的这三个参数都是描述符的集合,第一个rfds是用来保存这样的描述符的:当描述符的状态变成可读的时系统就会告诉select函数返回,第二个wfds是指有描述符状态变成可写的时系统就会告诉select函数返回,第三个参数efds是特殊情况,即描述符上有特殊情况发生时系统会告诉select函数返回。下面以一个输入为例来说明:


int fd1, fd2;         /* 在定义两个描述符*/


fd1 = socket(...);    /* 创建socket连接*/


fd2 = open(“/dev/tyS<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0”,O_RDWR); /* 打开一个串口*/


FD_ZERO(&rfds);       /* select函数之前先把集合清零 */


FD_SET(fd1, &rfds);   /* 分别把2个描述符加入读监视集合里去 */


FD_SET(fd2, &rfds);


int maxfd = 0;


maxfd = (fd1>fd2)?(fd1+1)fd2+1);           /* 注意是最大值还要加1 */


ret = select(maxfd, &rfds, NULL, NULL, &tv); /*然后调用select函数*/


这样就可以使用一个开关语句(switch语句)来判断到底是哪一个输入源在输入数据。具体判断如下:


switchret{


case -1perror("select");/* 这说明select函数出错 */


case 0printf("超时\n"); /* 说明在设定的时间内,socket的状态没有发生变化 */


default


ifFD_ISSET(fd1, &rfds) 处理函数1();/*socket有数据来*/


ifFD_ISSET(fd2, &rfds) 处理函数2();/*ttyS0有数据来*/


}


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2012-10-11 17:16

学习了。
相关推荐阅读
用户1002145 2009-12-28 09:01
sep4020移植Mplayer
sep4020移植mplayer1.交叉编译环境的建立:首先,下载一个arm-linux-gcc-3.3.2.tar.bz2的交叉编译工具可以从www.armfans.net上下载到拷贝到根目录下解压...
用户1002145 2009-12-23 19:12
Madplay移植到sep4020终极版
Madplay移植到sep4020终极版<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&g...
用户1002145 2009-12-17 22:22
minigui1.6.10的安装笔记
首先,从飞漫的网站上下载相关的压缩包:http://sourceforge.net/project/showfiles.php?group_id=231764&package_id=28101...
用户1002145 2009-12-17 20:36
sep4020一个中断测试程序(ADS环境下)
闲来无事,搭建一个外部中断的验证性小实验和大家分享下:首先先看看我搭建的电路图:用画图工具画的,比较简陋,见谅啊 ^_^接下来送上我的ADS调试小程序:#include<stdio.h>#...
用户1002145 2009-12-15 08:50
基于sep4020的数码管显示(ADS环境下)
基于sep4020的ADS的数码管显示<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />...
用户1002145 2009-12-15 08:49
sep4020控制8*8点阵LED显示(ADS环境下)
今天用8*8点阵LED做了个小实验,和大家一起分享下。(这里说明下,我用的8*8LED是SD411288)8*8点阵LED有16个引脚,为了找到相应的引脚的功能真的是不容易啊。最后,我是通过接5V电源...
我要评论
1
7
关闭 站长推荐上一条 /3 下一条