select
//select(maxfd,rset,wset,eset,timeout); r读,w写,e错误,timeout多长时间轮询一次
//有事件就返回
//rset--> uL fds_bites[_FD_SIZE/(8*sizeof(long))]
//#define _FD_SIZE 1024 默认值1024,内核定义fd_set rfds , rset;
FD_ZERO(&rfds);
FD_SET(sockfd,&rfds);int maxfd=sockfd;while(1){rset=rfds;int nready=select(maxfd+1,&rset,NULL,NULL,NULL);//事件个数if(FD_ISSET(sockfd,&rset)){int clientfd=accept(sockfd,(struct sockaddr*)&clientaddr,&len);FD_SET(clientfd,&rfds);maxfd=clientfd;}int i=0;for(i=sockfd+1;i<=maxfd;i++){if(FD_SET(i,&rset)){// 读事件,发送//FD_CLR(i,&rfds);close(i);//第一层bit_set。第二层系统io}}
}
缺点:
内核每一次都需要拷贝rset,拷贝整个,有很多不需要;IO数量有限制;参数较多,许都需要单独维护