/* According to POSIX 1003.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);
FD_ZERO(fd_set *set);
以上是关于select和pselect技术的函数族。
下面对select和pselect函数原型的说明:
Select和pselect都是等待一系列的文件描述符(int)的状态发生变化。
这两个函数基本上是一致,但是有三个区别:
第一点 select函数用的timeout参数,是一个timeval的结构体(包含秒和微秒),然而pselect用的是一个timespec结构体(包含秒和纳秒)
第二点 select函数可能会为了指示还剩多长时间而更新timeout参数,然而pselect不会改变timeout参数
第三点 select函数没有sigmask参数,当pselect的sigmask参数为null时,两者行为时一致的。
三个独立的文件描述符集合将会被监视,在readset中的文件描述符将会被监视是不是可读,就是说读这个文件描述符是否会发生阻塞。同理writeset集合将会被监视写过程是不是会被阻塞,exceptfds 将会被监视是否会发生异常。函数退出的时候,这些文件描述符集合将会发生改变用于标示文件描述符的状态变化。
有四个宏函数是用于提供多工集合监视的:FD_ZERO用以清空一个集合,FD_SET和FD_CLR是用来从一个集合中添加和删除一个文件描述符,FD_ISSET是用来测试一个文件描述符是不是在一个集合中。
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;
}