LT模式下epoll一直通知可写怎么办?

简介: LT模式下epoll一直通知可写怎么办?

使用Linux epoll模型的LT水平触发模式,当socket可写时,会不停的触发socket可写的事件,如何处理?

-----网络流传的腾讯面试题

方法一:每一次需要写入时,将fd加入epoll,轮询到可写并写完数据后,将fd移除epoll管理

既然当socket可写时,会不停触发事件,那么从一开始就将需要写入的fd不加入epoll的EPOLLOUT事件中,当需要写入的时候,再加入epoll管理,轮询fd可写,数据全部写完后,将fd移除epoll管理,避免反复通知

这种方法需要反复添加和删除

方法二:需要写入时,直接调用send或write,当返回错误码EAGAIN时,才将fd加入epoll管理,等待fd可写后写入数据,写入完成后,将fd移出epoll

改进的做法相当于认为socket在大部分时候是可写的,不能写了再让epoll帮忙监控

鄙人根据方法二写的send函数:

int epoll_LT_send(int fd, char *buf, int length) {
    int ret = send(fd, buf, length, 0); // 需要写入时,直接调用send
    if (ret < 0) { // 当返回错误码EAGAIN时,才将fd加入epoll管理
        if(errno == EAGAIN || errno == EWOULDBLOCK) { 
            int epfd = epoll_create(1);
            if (epfd == -1) {
                perror("epoll_create");
                return -1;
            }
            
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = EPOLLOUT;
    // 将fd加入epoll管理
            if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) { 
                perror("epoll_ctl");
                close(epfd);
                return -1;
            }
            ret = 0;
            while(1) { // 等待fd可写后写入数据
                struct epoll_event events;
                int nready = epoll_wait(epfd, &events, 1, -1);
                if (nready == -1) {
                    perror("epoll_wait");
                    close(epfd);
                    return -1;
                } else if (nready == 0) {
                    continue;
                }
            
                do { // 写入数据
                    int r = send(fd, buf+ret, (length - ret), 0);
                    if (r > 0) {
                    ret += r;
                    } else if (r == -1) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK) {
                            close(epfd);
                            return ret;
                        } else {
                            perror("send");
                            close(epfd);
                            return -1;
                        }
                    }
                
                } while (ret < length);
                break;
            } 
    // 写入完成后,将fd移出epoll
        epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev);
        }
    return ret;
        
    } else if (ret == 0) { // disconnect
        perror("send");
        return -1;
    }
    
return ret;
}

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

目录
相关文章
|
6月前
|
监控 网络协议 大数据
epoll中的ET和LT模式区别
epoll中的ET和LT模式区别
109 0
|
6月前
|
网络协议
Epoll事件ET和LT模型分析
Epoll事件ET和LT模型分析
71 0
|
5月前
|
数据处理
epoll的水平触发(LT)和边缘触发模式(ET)详解
epoll的水平触发(LT)和边缘触发模式(ET)详解
263 0
|
6月前
|
消息中间件 Unix Linux
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
439 0
|
6月前
|
监控 大数据 应用服务中间件
epoll的水平触发LT以及边沿触发ET的原理及使用及优缺点
epoll的水平触发LT以及边沿触发ET的原理及使用及优缺点
254 0
|
6月前
|
API
epoll监听信号事件-signalfd
epoll监听信号事件-signalfd
75 0
|
6月前
|
Linux
Linux网络编程(epoll的ET模式和LT模式)
Linux网络编程(epoll的ET模式和LT模式)
165 0
|
缓存 网络协议 程序员
举源码实例来说明epoll之LT和ET模式的区别
举源码实例来说明epoll之LT和ET模式的区别
146 0
基于epoll封装的事件回调miniserver
epoll技术前两节已经阐述过了,目前主要做一下封装,很多epoll的服务器都是采用事件回调方式处理, 其实并没有什么复杂的,我慢慢给大家阐述下原理。 在networking.h和networking.cpp里,这两个文件主要实现了一些文件读写功能的回调函数 。
931 0