IO多路复用
使用单线程处理多事件并发
- select
cpp
//创建套接字并监听
int sockfd = socket(...);
bind(sockfd,...);
listen(sockfd,n);
//接收来自客户端的连接,假设有5个
for(int i = 0; i < 5; ++i){
fds[i] = accept(sockfd,...);
if(fds[i] > max) max = fds[i];
}
//select:
fd_set rset;
while(1){
FD_ZERO(&rset); //置0
for(int i = 0; i < 5; ++i){
FD_SET(fds[i],&rset); //将对应的文件描述符在rset置1
}
select(max+1,&rset,NULL,NULL,NULL); //有文件描述符读到数据的话则返回;
for(int i = 0; i < 5; ++i){
if(FD_ISSET(fds[i],&rset)){ //找到有数据的文件描述符,处理
read(fds[i],buffer,sizeof(buffer)-1);
}
}
}
- poll
cpp
for(int i = 0; i < 5; ++i){
pollfds.fd = accept(sockfd,...);
pollfd.events = POLLIN;
}
while(1){
poll(pollfds,5,NULL);
for(i = 0; i < 5; ++i){
if(pollfds[i].revents & POLLIN){
pollfds[i].revent = 0;
read(pollfds[i].fd,buffer,sizeof(buffer));
}
}
}
- epoll
cpp
//epoll:
int server_fd,epoll_fd;
server_fd = socket(AF_INET, SOCK_STREAM, 0);
bind(...);
listen(...)
epoll_fd = epoll_create1(1);
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev); //注册
while (1) {
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); // 阻塞等待事件
for (int i = 0; i < num_events; i++) {
processing(...)处理
}
}