1 Unix环境高级I/O(Select)
允许进程高数内核等待多种I/O事件中的任何一种出现,并且进当这些时间中的一个或多个出现时,或这指定的时间已过去时才唤醒调用进程。因此函数有如下两种作用:
1. 等待多个I/O
2. 设置I/O操作超时
1.1 数据结构定义
#include <sys/time.h>
Struct timeval {
Time_t tv_sec; //second
Suseconds_t tv_usec; //microseconds
}
1.2 API
2.1 #include <semaphore.h> |
多路I/O |
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); |
返回: -1出现错误。0 在描述字就绪前时间到。正整数,就绪描述字个数 |
第一个参数n, 指明要被测试描述字个数,他的值是要被测试的最大描述符加1。Readfds, writefds, exceptfds,分别给出我们要求内核测试读,写,和例外条件的描述字集合。描述字集合类型为fd_set,由下面几个函数使用。这3个参数任意一个豆科一时空指针。当3个参数都为空时, select函数为定时器,其精度高于sleep。最后一个参数timeout,告诉内核等待指定描述府多长时间。分三种情况:
永远等待。无时间限制,仅当指定的描述字种有I/O就绪时才返回。Timeout 为空。
等待固定一段时间。等待时间由timeout参数指定
不等待。Timeout所指timeval结构体成员均为0
2.2 #include <semaphore.h> |
描述字属性集合操作宏 |
初始描述字集合fdset为空 |
void FD_ZERO(fd_set* fdset); |
无返回 |
将fileds从描述字集合fdset种清除 |
void FD_CLR(int filedes, fd_set* fdset); |
无返回 |
判断filedes属于fdset。 |
int FD_ISSET(int fileds, fd_set* fdset); |
返回:是返回非0,否0 |
将filedes加到描述字集合中 |
void FD_SET(int filedes, fd_set* fdset); |
无返回 |
1.3 Example
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
Int main(void) {
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now./n");
/* FD_ISSET(0, &rfds) will be true. */
Else
printf("No data within five seconds./n");
return 0;
}