select()系统调用

select()系统调用可以使进程检测同时等待的多个I/O设备,当没有设备准备好时,select()阻塞,其中任一设备准备好时,香港虚拟主机,select()就返回。

1: #include <sys/select.h> 2: #include <sys/time.h> 3:  4: int select(int maxfd, 5:fd_set *readfds, 6:fd_set *writefds, 7:fe_set *exceptfds,timeval *timeout); 9: 

select的第一个参数是文件描述符集中要被检测的比特数,这个值必须至少比待检测的最大文件描述符大1;参数readfds指定了被读监控的文件描述符集;参数writefds指定了被写监控的文件描述符集;而参数exceptfds指定了被例外条件监控的文件描述符集。参数timeout起了定时器的作用:到了指定的时间,无论是否有设备准备好,网站空间,都返回调用。

timeval的结构定义如下: struct timeval{    long tv_sec; //表示几秒    long tv_usec; //表示几微妙}

timeout取不同的值,该调用就表现不同的性质:

1.timeout为0,调用立即返回; 2.timeout为NULL,select()调用就阻塞,直到知道有文件描述符就绪;3.timeout为正整数,就是一般的定时器。

select调用返回时,除了那些已经就绪的描述符外,select将清除readfds、writefds和exceptfds中的所有没有就绪的描述符。select的返回值有如下情况:

1.正常情况下返回就绪的文件描述符个数; 2.经过了timeout时长后仍无设备准备好,返回值为0;3.如果select被某个信号中断,它将返回-1并设置errno为EINTR。4.如果出错,返回-1并设置相应的errno。

系统提供了4个宏对描述符集进行操作:

1: #include <sys/select.h> 2: #include <sys/time.h> 3: void FD_SET(int fd, fd_set *fdset); 4: void FD_CLR(int fd, fd_set *fdset); 5: void FD_ISSET(int fd, fd_set *fdset); 6: void FD_ZERO(fd_set *fdset);

宏FD_SET设置文件描述符集fdset中对应于文件描述符fd的位(设置为1),宏FD_CLR清除文件描述符集 fdset中对应于文件描述符fd的位(设置为0),宏FD_ZERO清除文件描述符集fdset中的所有位(既把所有位都设置为0)。使用这3个宏在调用select前设置描述符屏蔽位,在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被设置。

select的使用方法:

1. 将要监控的文件添加到文件描述符集 2. 调用Select开始监控3. 判断文件是否发生变化

如下:

FD_ZERO(&fds); //清空集合 FD_SET(fd1,&fds); //设置描述符FD_SET(fd2,&fds); //设置描述符maxfdp=fd1+1; //描述符最大值加1,假设fd1>fd2switch(select(maxfdp,&fds,NULL,NULL,&timeout))case -1: exit(-1);break; //select错误,美国服务器,退出程序case 0:break;default:if(FD_ISSET(fd1,&fds))…. //测试fd1是否可读

可运行源代码:

1: /** 2: * select()系统调用提供一种实现同步I/O多路复用机制 3: **/ 4:  5: /** 6: #include <unistd.h> 7: #include <sys/time.h> 8: #include <sys/types.h> 9: 10: 11: int select (int n, 12: fd_set *readfds, 13: fd_set *writefds, 14: fd_set *exceptfds, 15: struct timeval *timeout); 16: 17: FD_CLR(int fd, fd_set *set); 18: FD_ISSET(int fd, fd_set *set); 19: FD_SET(int fd, fd_set *set); 20: FD_ZERO(fd_set *set); 21: 22: **/ 23:  24: /** 25: timeval 26: #include <sys/time.h> 27: struct timeval { 28: long tv_sec; /* seconds 29: long tv_usec; /* microseconds 30: }; 31: 32: */ 33:  34:  35: /** 36: * select()示例程序 37: **/ 38:  39:  40: #include <stdio.h> 41: #include <sys/time.h> 42: #include <sys/types.h> 43: #include <unistd.h> 44: #include <fcntl.h> 45:  46: #define TIMEOUT 5/* select timeout in seconds */ 47: #define BUF_LEN 1024/* read buffer in bytes */ 48:  49: int max(int a,int b) 50: { 51:return (a>b)?a:b; 52: } 53:  54: int main (void) 55: { 56:struct timeval tv; 57:fd_set readfds; 58:int fd_open, fd ,maxfdp1; 59:int ret; 60:/* Wait on stdin for input. */ 61:  62:fd_open = open("select_test.c" ,O_RDONLY); 63:FD_ZERO(&readfds); 64:FD_SET(STDIN_FILENO, &readfds); 65:FD_SET(fd_open, &readfds); 66:/* Wait up to five seconds. */ 67:tv.tv_sec = TIMEOUT; 68:tv.tv_usec = 0; 69: 70:/* All right, now block! */ 71:maxfdp1 = max(STDIN_FILENO , fd_open) + 1; 72:ret = select(maxfdp1,&readfds,NULL,NULL, &tv); 73:  74:if(ret == -1){ 75:perror("select"); 76:return 1; 77:}else if(!ret){ 78:printf("%d seconds elapsed.\n", TIMEOUT); 79:return 0; 80:} 81: 82: /* 83: * Is our file descriptor ready to read? 84: * (It must be, as it was the only fd that 85: * we provided and the call returned 86: * nonzero, but we will humor ourselves.) 87: */ 88:  89:  90:if (FD_ISSET(STDIN_FILENO, &readfds)){ 91:char buf[BUF_LEN+1]; 92:int len; 93: 94:/* guaranteed to not block */ 95:len = read (STDIN_FILENO, buf, BUF_LEN); 96:if (len == -1){ 97:perror("read"); 98:// return 1; 99:} 100:if (len){ 101:buf[len] = ‘\0’; 102:printf("read: %s\n", buf); 103:} 104://return 0; 105:} 106:  107:if (FD_ISSET(fd_open, &readfds)){ 108:char buf[BUF_LEN+1]; 109:int len; 110: 111:/* guaranteed to not block */ 112:len = read (fd_open, buf, BUF_LEN); 113:if (len == -1){ 114:perror("read"); 115:// return 1; 116:} 117:if (len){ 118:buf[len] = ‘\0’; 119:printf("read: %s\n", buf); 120:} 121:// return 0; 122:} 123:  124: 125:fprintf (stderr, "This should not happen!\n"); 126:return 1; 127: } 128:  129: 

GCC编译通过,可以自行测试运行,本程序测试了两个描述符,一个标准输入,一个是文件描述符。

只有流过血的手指才能弹出世间的绝唱。

select()系统调用

相关文章:

你感兴趣的文章:

标签云: