尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

ET和LT详解

ET和LT详解 引用本篇文章是最后一篇关于《Linux高性能服务器编程》的总结我把这篇文章放在最后是因为我想通过这本书中大部分的项目实战总结出一些关于ET和LT的理解。简介水平触发这个是默认的工作模式如果我们不作任何的设置就默认是水平触发。采用LT的文件描述符当epoll_wait检测到其上有事件发生的时候通知应用程序应用程序可以不立即处理。则样子当应用程序下一次调用epoll_wait时还可以继续通知直到该事件被处理。而ET的文件描述符应用程序必须立刻处理该事件因为后续的epoll_wait不会再次通知该事件可见ET更加的高效因为只会通知一次不会多次触发epoll。LT作为LT我们不需要while循环来读取数据因为我们如果有数据没有读完我们可以等待下一轮的通知。就是在for循环里面我们对每一次的事件都只处理了一次不管处理完了没有如果处理完了那么这个事件就结束了如果没有处理完那么这个事件就会加入下一次的epoll当for结束了之后epoll又会再一次的通知直到没有数据可以读。这个效率其实比较低因为不断的通知会有内核到用户的切换性能低。// LT工作流程 void lt (epoll_event* events, int number, int epollfd, int listenfd) { char buf[BUFFER_SIZE]; for (int i 0; i number; i) { int sockfd events[i].data.fd; if (sockfd listenfd) { sockaddr_in clientAddress; socklen_t len sizeof(clientAddress); int connfd accept(listenfd, (sockaddr*)clientAddress, len); addFd(epollfd, connfd, false); } else if (events[i].events EPOLLIN) { // 只要socket缓存中还有未读出的数据这段代码就被触发 memset(buf, \0, sizeof(buf)); int ret recv(sockfd, buf, BUFFER_SIZE - 1, 0); if (ret 0) { close(sockfd); continue; } } else { /* code */ } } }ET我们ET因为只会通知一次事件所以一旦通知了就必须处理完否则这个事件就不会再一次处理了。所以我们用while来处理事件。然后因为ET不是默认的所以我们还要设置文件描述符的性质时ET// et的工作流程 void et (epoll_event* events, int number, int epollfd, int listenfd) { char buf[BUFFER_SIZE]; for (int i 0; i number; i) { int sockfd events[i].data.fd; if (sockfd listenfd) { sockaddr_in clientAddress; socklen_t len sizeof(clientAddress); int connfd accept(listenfd, (sockaddr*) clientAddress, len); addFd(epollfd, connfd, true); } else if (events[i].events EPOLLIN) { // 这段代码不会重复触发所以我们要循环读取数据以确保把socket读缓存里面的数据全部读完 while(1) { memset(buf, \0, BUFFER_SIZE); int ret recv(sockfd, buf, BUFFER_SIZE - 1, 0); if (ret 0) { // 对于非阻塞IO下面条件成立表示数据已经全部读取完毕此后epoll就可以被再一次触发sockfd上的EPOLLIN事件以驱动下一次读操作 if (errno EAGAIN || errno EWOULDBLOCK) { close(sockfd); break; } else if (ret 0) { close(sockfd); } else { std::cout buf std::endl; } } else { std::cout something else happened std::endl; } } } } }其实这两个并没有好坏之分LT的性能虽然低但是可以保证每一个事件都可以得到及时的处理一旦一个事件读取或者写入的时间比较长而我们选择了ET那么一个事件就会卡特别久导致其他事件根本没有被处理。但是如果每个事件的处理时间不长那么选择ET是一个比较好的选择可以避免系统在内核和用户之间的切换。总结本系列《Linux高性能服务器编程》的内容就到这里结束了如果大家能看到这里十分的感谢大家的陪伴。真心希望可以帮助大家理解同时也监督我自己的学习~~~~
返回列表