参数说明:fd_set 是一个结果体struct fd_set,该结构是一个文件描述符集合;
struct timeval是一个关于时间设置的结构体:
struct timeval
{
time_t tv_sec;/*seconds*/
suseconds_t tv_usec;/*microseconds*/
}
参数意义:readfds 指向读文件描述集合,用来监控这个集合中是否有描述符可以读;writefds指向写文件描述集合,用来监控这个集合中是否有描述符可以写;errorfds用来监视文件错误异常。
Maxfdp 是所有打开的文件描述中最大的那个再加上1。
Timeout:
(1)当它为NULL的时候,表示select一直处于阻塞状态,直到readfds、writefds、errorfds这三个集合中有一个状态发生了改变selcet函数才返回。
(2)当它为{0,0}时,表示select处于非阻塞状态,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值。
(3)当它设置了时间值时(如3妙),如果在设置的时间内没有状态改变则select函数返回0,表示超时。
Select函数的返回值:
(1) 小于0表示调用select出错了
(2) 等于0表示设置了超时了
(3) 大于0(返回文件描述词状态已改变的个数)表示要监控的三个集合中有一个状态发生了改变—有文件描述符可读可写或者出错了。此时参数readfds,writefds,exceptfds和timeout的值变成不可预测。
EBADF 文件描述词为无效的或该文件已关闭
EINTR 此调用被信号所中断
EINVAL 参数n 为负值。
ENOMEM 核心内存不足
关于select有几个宏:
FD_ZERO(fd_set* set) //清空集合set中的文件描述
FD_SET(int fd, fd_set* set) //将文件描述符加入到集合set中去
FD_CLR(int fd, fd_set* set) //将文件描述符从集合set中清除
FD_ISSET(int fd, fd_set* set) //判断集合set中的文件描述符fd是否为真(状态发生改变)
#include <sys/time.h> //need time
#include <stdio.h> //need io input and output
#include <sys/types.h> //type define
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
int main ()
{
int keyboard;
int ret, i;
char str[10];
fd_set readfd;
time_t select_start_time, select_end_time;
struct timeval timeout;
/*ÉèÖó¬Ê±µÄʱ¼äΪ3Ãë*/
timeout.tv_sec = 5;
timeout.tv_usec = 0;
/*´ÓÖն˶ÁÈ¡Êý¾Ý*/
keyboard = open("/dev/tty", O_RDONLY | O_NONBLOCK);
/*±£Ö¤ÖÕ¶ËÕýÈ·´ò¿ªÁË*/
assert(keyboard > 0);
while(1)
{
/*½«¼¯ºÏreadfdÖеÄÎļþÃèÊö·ûÇåÁã*/
FD_ZERO(&readfd);
/*½«ÎļþÃèÊö·û¼ÓÈ뼯ºÏreadfdÖÐ*/
FD_SET(keyboard, &readfd);
/*¼ì²â¶Á¼¯ºÏÖÐÊÇ·ñÓÐÊý¾Ý¿É¶Á*/
time(&select_start_time);
ret = select(keyboard+1, &readfd, NULL, NULL, &timeout);
/*ÔÚ3ÃîÖ®ÄÚ¼à¿ØµÄÎļþÃèÊö·ûÓÐÊý¾Ý¿É¶Á*/
if (ret > 0)
{
/*Åжϼ¯ºÏreadfdÖеÄÎļþÃèÊö·ûkeyboardÊÇ·ñÓÐÊý¾Ý¿É¶Á*/
if (FD_ISSET(keyboard, &readfd))
{
/*¶ÁÈ¡9¸ö×Ö½ÚµÄÊý¾Ý,Èç¹ûûÓÐ9¸ö×Ö½ÚµÄÊý¾Ý¾Í¶Áȡʵ¼ÊµÄ×Ö½ÚÊý£¨Èç3¸ö£©*/
i = read(keyboard, str, 9);
/*×Ö·û´®Ä©Î²¼Ó\0*/
str[i] = '\0';
printf("get data from tty is %s\n", str);
}
}
/*Ôڹ涨µÄʱ¼äÄÚûÓÐÊý¾Ý¿É¶Á£¨³¬Ê±ÁË£©*/
else if ( ret == 0)
{
printf("select time out\n");
break;
}
/*µ÷ÓÃselectº¯Êý³ö´íÁË*/
else
{
printf("select error\n");
break;
} /*end if*/
} /*end while*/
time(&select_end_time);
printf("select run time is %d\n", (select_end_time - select_start_time));
} /*end main*/