linux 下的select函数

函数原型

  /* According to POSIX.1-2001 */
       #include <sys/select.h>  //头文件

       /* According to earlier standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);//函数原型

描写叙述

       Three independent sets of file descriptors are watched.  Those listed in readfds will be watched to see if characters  become  avail‐
       able  for  reading  (more precisely, to see if a read will not block; in particular, a file descriptor is also ready on end-of-file),
       those in writefds will be watched to see if a write will not block, and those in exceptfds will be watched for exceptions.  On  exit,
       the  sets  are  modified in place to indicate which file descriptors actually changed status.  Each of the three file descriptor sets
       may be specified as NULL if no file descriptors are to be watched for the corresponding class of events.
//该函数同意进程指示等待多个事件的不论什么一个发生。而且仅仅在有一个或多个事件发生或者经历一段指定的时间后才唤醒它
它仅仅有在例如以下四种情况下返回
1. 集合中的不论什么描写叙述符准备好读
2. 集合中的不论什么描写叙述符准备好谢
3. 集合中的不论什么描写叙述符有异常等待处理
4. 等待事件到达

       The time structures involved are defined in <sys/time.h> and look like

           struct timeval {
               long    tv_sec;         /* seconds */
               long    tv_usec;        /* microseconds */
           };
等待事件这个參数有三种可能

1.永远灯下去。仅在有一个描写叙述符准备好才返回。为此。我们把该參数设置为空指针

2.等待一段固定时间。在有一个描写叙述符准好好I/O才返回,可是不能超时;

3. 不等待,检查描写叙述符后马上返回,这时定时器的时间必须设置为0

返回值:
(1)正常情况下返回满足要求的文件描写叙述符个数。
(2)经过了timeout等待后仍无文件满足要求。返回0。
(3)假设select被某个信号中断,将返回-1并设置errno为EINTR;
(4)若出错。返回-1并设置对应的errno。

select的用法:
(1)将要监控的文件加入到文件描写叙述符集。
(2)调用select開始监控;
(3)推断文件是否发生变化;

系统提供四个宏对描写叙述符集进行操作:

void FD_SET(int fd, fd_set *fdset); //将文件描写叙述符fd加入到文件描写叙述符集fdset中。
void FD_CLR(int fd, fd_set *fdset); //从文件描写叙述符集fdset中清除文件描写叙述符fd;
void FD_ISSET(int fd, fd_set *fdset); //在调用select后使用FD_ISSET来检測文件描写叙述符集中的文件fd发生了变化
void FD_ZERO(fd_set *fdset);//清空文件描写叙述符集

以下看个样例。用select来监视stdin看何时有输入


root@wl-Lenovo-B590:/myworkspace/anvancdedprogramminginunix/mysourcecode/chapter11#   cat -n select.c 
     1	       #include <stdio.h>
     2	       #include <stdlib.h>
     3	       #include <sys/time.h>
     4	       #include <sys/types.h>
     5	       #include <unistd.h>
     6	
     7	       int
     8	       main(void)
     9	       {
    10	           fd_set rfds;
    11	           struct timeval tv;
    12	           int retval;
    13	
    14	           /* Watch stdin (fd 0) to see when it has input. */
    15	           FD_ZERO(&rfds);
    16	           FD_SET(0, &rfds);
    17	
    18	           /* Wait up to five seconds. */
    19	           tv.tv_sec = 5;
    20	           tv.tv_usec = 0;
    21	
    22	           retval = select(1, &rfds, NULL, NULL, &tv);
    23	           /* Don't rely on the value of tv now! */
    24	
    25	           if (retval == -1)
    26	               perror("select()");
    27	           else if (retval)
    28	               printf("Data is available now.
");
    29	               /* FD_ISSET(0, &rfds) will be true. */
    30	           else
    31	               printf("No data within five seconds.
");
    32	
    33	           exit(EXIT_SUCCESS);
    34	       }

编译后执行结果如图:

linux  下的select函数

能够看到,五秒不输入则到达定时时间。有输入则会捕捉到


參考: UNIX网络编程

           Linux Programmer's Manual