#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); void FD_CLR(int fd, fd_set *set);将fd从set中清除出去(在集合中是1,清除出去就成0,set其实是位图) int FD_ISSET(int fd, fd_set *set);判断fd是否在集合中; void FD_SET(int fd, fd_set *set);将fd设置到集合中去; void FD_ZERO(fd_set *set); 将set清空成0; int nfds:所监听的所有文件描述符中,最大的文件描述符+1; 参数2,3,4分别对应:所监听的文件描述符“可读"事件;readfds() 所监听文件描述符"可写"事件;writefds() 所监听文件描述符"异常“事件; timeval:轮训时间,到时select返回; 返回值:成功返回所监听的所有的监听集合中,满足条件的总数; 失败:-1 并且设置errno fd_set *readfds, fd_set *writefds,fd_set *exceptfds这三个参数是传入传出参数;例如有lfd ,fd1 ,fd2,fd3;fd_set readfds; FD_ZERO(&readfds);//清空整个readfds; FD_SET(lfd,&readfds); FD_SET(fd1,&readfds); FD_SET(fd2,&readfds); FD_SET(fd3,&readfds); 此时readfds中lfd,fd1,fd2,fd3标志位都变成1; 然后调用select后返回,假设lfd,fd3有变化,这时readfds集合中fd1和fd2会清理变成0,lfd和fd3还是1,所以才能使用FD_ISSET判断返回的描述符是否在集合中; FD_ISSET(lfd,&readfds);因为lfd在,所以返回值是1; FD_ISSET(fd1,&readfds);因为fd1不在,所以返回值是0; select函数缺点:1文件描述符上限,因为一个进程能打开的最大文件是1024个,所以select最大能监听的的文件描述符是1024; 2.当select监听的描述符比较少的时候可以构建一个数组,把要监听的描述符放进数组,然后遍历素组中的每一个数据; 3.监听集合和满足条件的监听集合都是同一个,所以每次使用都要将原有集合保存;
