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

目录
相关文章
|
存储 缓存 NoSQL
Redis过期Key的清理机制
Redis过期Key的清理机制
262 1
|
11月前
|
缓存 监控 数据挖掘
C# 一分钟浅谈:性能测试与压力测试
【10月更文挑战第20天】本文介绍了性能测试和压力测试的基础概念、目的、方法及常见问题与解决策略。性能测试关注系统在正常条件下的响应时间和资源利用率,而压力测试则在超出正常条件的情况下测试系统的极限和潜在瓶颈。文章通过具体的C#代码示例,详细探讨了忽视预热阶段、不合理测试数据和缺乏详细监控等常见问题及其解决方案,并提供了如何避免这些问题的建议。
249 7
|
测试技术 Python
|
缓存 并行计算 Ubuntu
在Ubuntu系统下部署大语言模型
在Ubuntu系统下部署大语言模型
673 0
|
存储 并行计算 程序员
pthread_create函数详解
pthread_create函数详解
|
存储 编解码 vr&ar
色彩空间与像素格式
颜色是不同波长的光对人眼刺激产生的色彩感觉。色彩空间(Color Space)是颜色的数学表示,根据不同的表示方法分为不同的色彩模型。最常用的色彩模型有三类:RGB(用于计算机图形学), YUV(用于视频系统), CMYK(用于彩色印刷)。后文对色彩空间与色彩模型的叫法不作区分。本文仅讨论视频图像处理领域常用的 RGB 色彩空间和 YUV 色彩空间。
3163 0
色彩空间与像素格式
|
消息中间件 存储 安全
zeromq无锁队列的原理与实现
zeromq无锁队列的原理与实现
335 0
|
存储 算法 关系型数据库
Ceph之数据分布:CRUSH算法与一致性Hash
转自于:http://www.cnblogs.com/shanno/p/3958298.html?utm_source=tuicool 数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以下三个因素: 1) 故障域隔离。
2077 0
|
机器学习/深度学习 存储
进制及进制转换详解。原码、反码、移码,补码区别介绍。(通俗易懂)
Ⅰ.进制转换详解。Ⅱ.原码、反码、移码,补码区别介绍。(通俗易懂)
721 0
进制及进制转换详解。原码、反码、移码,补码区别介绍。(通俗易懂)