Linux提供了同步I/O多路复用(synchronous I/O multiplexing)方法select,该方法主要用户监测多个文件描述符是否准备好,也就是说该方法主要是监测I/O是否可操作,或者是出现了异常,不过它一次可以监视很多个文件描述符。select函数原型如下:

 

 
  
  1. int select(int nfds, fd_set *readfds, fd_set *writefds, 
  2. fd_set *exceptfds, struct timeval *utimeout); 

 

其中,readfdswritefdsexceptfds是三个待观察的文件描述符集合,在调用select函数前我们准备好待考察的文件描述符,根据需求分别放入相应集合中,如同参数名描述的那样,我们将等待可读的文件描述符放入readfds集合,将等待可写的放入writefds集合,将判断是否出现错误的描述符放入exceptfds集合。当select返回时,相应的集合中的文件描述符只剩下了符合期望的;当然这三个参数可以为nil。参数nfds指明传入select方法的文件描述符的总数,相同描述符同时放入多个集合只计数1select方法是阻塞执行的,可以使用utimeout参数指定没有相应事件发生的时候,select方法最长执行多长时间。

Linux同时还提供了一个pselect函数,该函数定义如下:

 

 
  
  1. int pselect(int nfds, fd_set *readfds, fd_set *writefds,  
  2. fd_set *exceptfds, const struct timespec *ntimeout, 
  3. const sigset_t *sigmask); 

 

从函数定义上来看,它与select方法有两处不同,第一是超时timeout不同,它们的数据类型不同,utimeout的数据类型是timevalntimeout的数据类型是timespec,它们的定义如下:

 

 

 
  
  1. struct timeval{ 
  2. time_t tv_sec;  /* seconds */ 
  3. long tv_usec;   /* microseconds */  
  4. struct timespec{ 
  5. long tv_sec;    /*  seconds  */ 
  6. long tv_nsec;   /*  nanoseconds  */ 

也就是说select的超时只能达到毫秒级,而pselect可以达到纳秒级;同时在select中超时是通过指针传引用的,select方法会更新这个参数,指明还剩多长时间就会超时。