linux epoll,poll,select
发布时间:2020-12-13 23:40:17 所属栏目:Linux 来源:网络整理
导读:epoll函数用法,还有点poll和select 1,LT的epoll是select和poll函数的改进版。 特点是,读完缓冲区后,如果缓冲区还有内容的话,epoll_wait函数还会返回,直到把缓冲区全部读完。 2,ET的epoll(阻塞) 特点是,读完缓冲区后,不管缓冲区还有没有内容,epol
epoll函数用法,还有点poll和select1,LT的epoll是select和poll函数的改进版。特点是,读完缓冲区后,如果缓冲区还有内容的话,epoll_wait函数还会返回,直到把缓冲区全部读完。 2,ET的epoll(阻塞)特点是,读完缓冲区后,不管缓冲区还有没有内容,epoll_wait函数都不会再返回,直到对端再一次发送信息过来。估计有的读者朋友会想到用while去读,但是有个致命的问题,因为文件描述符是阻塞的,所以当全部读完后,进程就会阻塞在recv函数那里,就不能够再处理别的连接了。 3,ET的epoll(非阻塞),效率最高的使用方法。特点是,读完缓冲区后,不管缓冲区还有没有内容,epoll_wait函数都不会再返回,直到对端再一次发送信息过来。但是可以事先用fcntl把文件描述符设置成非阻塞的方式,让后用while一直去读,当全部读完后,recv函数也不会阻塞。 ET的epoll(非阻塞)的例子: #include <stdio.h> #include <sys/epoll.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> int main(int argc,char** argv){ int port = atoi(argv[1]); int lfd = socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; bind(lfd,(struct sockaddr*)&addr,sizeof(addr)); listen(lfd,5); int efd = epoll_create(10); struct epoll_event re; re.events = EPOLLIN; re.data.fd = lfd; epoll_ctl(efd,EPOLL_CTL_ADD,lfd,&re); struct epoll_event events[100]; while(1){ int ret = epoll_wait(efd,events,100,-1); printf("======================wait=======n"); if(ret == -1){ perror("epoll_wait"); exit(1); } for(int i = 0; i < ret; ++i){ if(events[i].data.fd == lfd){ int cfd = accept(lfd,NULL,NULL); int flags = fcntl(cfd,F_GETFL); flags |= O_NONBLOCK; fcntl(cfd,F_SETFL,flags); struct epoll_event re; re.events = EPOLLIN | EPOLLET; re.data.fd = cfd; epoll_ctl(efd,cfd,&re); break; } char buf[3]; int ret; while((ret = recv(events[i].data.fd,buf,sizeof buf,0)) > 0){ write(STDOUT_FILENO,ret); } if(ret == 0){ epoll_ctl(efd,EPOLL_CTL_DEL,events[i].data.fd,NULL); close(events[i].data.fd); printf("client disconnetn"); } else if(ret == -1 && errno == EAGAIN){ printf("read overn"); } } } } poll函数例子: #include <stdio.h> #include <poll.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> int main(int argc,5); struct pollfd pfd[1024]; for(int i = 0; i < 1024; ++i){ pfd[i].fd = -1; } pfd[0].fd = lfd; pfd[0].events = POLLIN; nfds_t maxfd = 0; while(1){ int ret = poll(pfd,maxfd + 1,-1); printf("--------------poll------n"); if(pfd[0].revents & POLLIN){ int cfd = accept(lfd,NULL); for(int i = 0; i < 1024; ++i){ if(pfd[i].fd == -1){ pfd[i].fd = cfd; pfd[i].events = POLLIN; maxfd++; break; } } continue; } for(int i = 0; i <= maxfd; ++i){ if(pfd[i].revents & POLLIN){ char buf[64]; int ret = recv(pfd[i].fd,0); if(ret == 0){ pfd[i].fd = -1; close(pfd[i].fd); printf("client is disconnetn"); } else{ write(STDOUT_FILENO,ret); } } } } } 通过对比epoll和poll的例子可以看出来:
c/c++ 学习互助QQ群:877684253本人微信:xiaoshitou5854(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |