函数select(UNIX环境高级编程笔记)
I/O多路转接(I/O multiplexing)。为了事项I/O多路转接,先构造一张我们感兴趣的描述符(通常都不止一个)的列表,然后调用一个函数,知道这些描述符中一个已经准备好进行I/O时,该函数才返回、poll、pselect和select这3个函数使我们能够执行I/O多路转接。在从这些函数返回时,进程会被告知那些描述符已经准备好可以进行I/O。
函数select
在所有POSIX兼容的平台上,select函数使我们可以执行多个I/O多路转接。传给select的参数告诉内核:
● 我们所关心的描述符;
● 对于 每个描述符我们所关心的条件。
● 愿意等待多上时间。
从select返回时,内核告诉我们:
● 已准备好的描述符的总数量;
● 对于读、写或异常这3个条件中的每一个,哪些描述符已经准备好。
#include <sys/select.h> int select(int maxfd1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr); 返回值:准备就绪的描述符数目;若超时,返回0;若出错,返回-1 |
---|
中间3个参数readfds、writefds和exceptfds是指向描述符集的指针。每个描述符集存储在一个fd_set数据类型中。这个数据类型是由实现选择的,它可以为每一个可能的描述符保持一位。我们可以认为它只是一个很大的字节数组,如图所示:
对于fd_set数据类型,只可以进行以下处理:分配一个这种类型的变量,将这种类型的变量赋值给同类型的另一个变量,或者对这种类型的变量使用下列函数中的一个:
#include <sys/select.h> int FD_ISSET(int fd, fd_set *set); 返回值:若fd在描述符集中,返回非0值;否则,返回0 void FD_CLR(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); |
---|
select的中间3个参数(指向描述符集的指针)中的任意一个都可以是空指针,这表示对相应条件并不关心。如果所有的3个指针都是NULL,则select提供了比sleep更精确的定时器。
select的第一个参数maxfdp1的意思是“最大文件描述符编号值加1”。在3个描述符集中找出最大描述符值,然后加1,