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

目录
相关文章
|
7月前
|
监控 网络协议 大数据
epoll中的ET和LT模式区别
epoll中的ET和LT模式区别
126 0
|
7月前
|
网络协议
Epoll事件ET和LT模型分析
Epoll事件ET和LT模型分析
75 0
浅谈select,poll和epoll的区别
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! select,poll和epoll其实都是操作系统中IO多路复用实现的方法。 select select方法本质其实就是维护了一个文件描述符(fd)数组,以此为基础,实现IO多路复用的功能。
浅谈select,poll和epoll的区别
|
6月前
|
数据处理
epoll的水平触发(LT)和边缘触发模式(ET)详解
epoll的水平触发(LT)和边缘触发模式(ET)详解
303 0
|
7月前
|
消息中间件 Unix Linux
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
【ZMQ polling机制】ZMQ异步接收机制以及与epoll/select的对比分析
497 0
|
7月前
|
API
epoll监听信号事件-signalfd
epoll监听信号事件-signalfd
84 0
|
7月前
|
Linux
Linux网络编程(epoll的ET模式和LT模式)
Linux网络编程(epoll的ET模式和LT模式)
170 0
|
网络协议 Linux
linux下select、poll、epoll机制使用介绍
在上一篇文章编写了一个 Linux下基于TCP协议的群聊系统设计(多线程+select) 案例,演示了select函数的使用方法。这篇文章接着介绍剩下的poll、epoll函数。并且也是使用群聊系统的案例编写例子,方便理解实际用法。 下面先介绍这3种函数的原型和相关头文件 虽然select在上篇文章里已经介绍过,这里为了方便比较这3个函数,再把select详细介绍粘贴过来。
439 0
|
缓存 网络协议 程序员
举源码实例来说明epoll之LT和ET模式的区别
举源码实例来说明epoll之LT和ET模式的区别
151 0
彻底学会使用epoll(二)——ET和LT的触发方式
分析了ET和LT的实现方式,那么分析他们的触发方式就容易多了。我们通过实现分析知道LT模式下epoll_wait被唤醒可以通过两种方式(图中红线和蓝线),而ET模式只能通过一种方式(图中红线)。
1510 0