/* 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);
以上是關(guān)于select和pselect技術(shù)的函數(shù)族。
下面對select和pselect函數(shù)原型的說明:
Select和pselect都是等待一系列的文件描述符(int)的狀態(tài)發(fā)生變化。
這兩個(gè)函數(shù)基本上是一致,但是有三個(gè)區(qū)別:
第一點(diǎn) select函數(shù)用的timeout參數(shù),是一個(gè)timeval的結(jié)構(gòu)體(包含秒和微秒),然而pselect用的是一個(gè)timespec結(jié)構(gòu)體(包含秒和納秒)
第二點(diǎn) select函數(shù)可能會為了指示還剩多長時(shí)間而更新timeout參數(shù),然而pselect不會改變timeout參數(shù)
第三點(diǎn) select函數(shù)沒有sigmask參數(shù),當(dāng)pselect的sigmask參數(shù)為null時(shí),兩者行為時(shí)一致的。
三個(gè)獨(dú)立的文件描述符集合將會被監(jiān)視,在readset中的文件描述符將會被監(jiān)視是不是可讀,就是說讀這個(gè)文件描述符是否會發(fā)生阻塞。同理writeset集合將會被監(jiān)視寫過程是不是會被阻塞,exceptfds 將會被監(jiān)視是否會發(fā)生異常。函數(shù)退出的時(shí)候,這些文件描述符集合將會發(fā)生改變用于標(biāo)示文件描述符的狀態(tài)變化。
有四個(gè)宏函數(shù)是用于提供多工集合監(jiān)視的:FD_ZERO用以清空一個(gè)集合,FD_SET和FD_CLR是用來從一個(gè)集合中添加和刪除一個(gè)文件描述符,FD_ISSET是用來測試一個(gè)文件描述符是不是在一個(gè)集合中。
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;
}