关于epoll的调试的几个问题

2023-05-16

将今天调试的几个小问题点总结下,后续遇到再添加。

一 将总结的问题点放在最前面 

1 epoll_wait的maxevents参数

epoll_wait的maxevents参数,经过测试,maxevents的值可以小于监听的描述符总数。我在下面的测试代码中,将这个值改为1,也是可以同时处理两个客户端的。

2 删除文件事件集合中的文件描述符

如下所示,最后一个参数设置为NULL即可;

ret = epoll_ctl(epfd, EPOLL_CTL_DEL,sockfd, NULL);

设置为下面的形式,就是最后一个参数配置为何EPOLL_CTL_ADD时相同也没问题:

ev.events = EPOLLIN | EPOLLET;
ev.data.fd = sockfd;
ret = epoll_ctl(epfd, EPOLL_CTL_DEL,sockfd, &ev);

3 EPOLL_CTL_DEL调用要在close之后

如果调用EPOLL_CTL_DEL之前先调用close。就会报错:

EPOLL_CTL_DEL: Bad file descriptor

二 基础相关

相关结构体:

     typedef union epoll_data {
        void *ptr;
        int fd;
        __uint32_t u32;
        __uint64_t u64;
     } epoll_data_t;
      //感兴趣的事件和被触发的事件
     struct epoll_event {
        __uint32_t events; /* Epoll events */
        epoll_data_t data; /* User data variable */
     };

函数

     int epoll_create(int size);

 size只要是大于的1的数任意数都可以:老师说的。老师有理

     int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

其中参数epfd表示要操作的文件描述符,它是epoll_create的返回值;第二个参数op表示动作,使用以下三个宏来表示:

· EPOLL_CTL_ADD:注册新的fd到epfd中。

· EPOLL_CTL_MOD:修改已经注册的fd的监听事件。

· EPOLL_CTL_DEL:从epfd中删除一个fd。 

第三个参数fd是op实施的对象,即需要操作的文件描述符;第四个参数event是告诉内核需要监听什么事件,events可以是以下几个宏的集合:· EPOLLIN:表示对应的文件描述符可以读(包括对SOCKET正常关闭)。· EPOLLOUT:表示对应的文件描述符可以写。· EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来)。· EPOLLERR:表示对应的文件描述符发生错误。· EPOLLHUP:表示对应的文件描述符被挂断。· EPOLLET:将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。 · EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。

     #include <sys/epoll.h>
     int epoll_wait ( int epfd, struct epoll_event* events, int maxevents, int
timeout );

其中参数epfd表示要操作的文件描述符,它是epoll_create的返回值;events指向检测到的事件集合,将所有就绪的事件从内核事件表中复制到它的第二个参数events指向的数组中;maxevents指定最多监听多少个事件;timeout指定epoll的超时时间,单位是毫秒。当timeout设置为‒1时,epoll_wait调用将永远阻塞,直到某个事件发生;当timeout设置为0时,epoll_wait调用将立即返回;当timeout设置为大于0时,表示指定的毫秒。函数执行成功时返回就绪的文件描述符的个数,失败时返回‒1并设置errno。 

三 测试代码

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/epoll.h>
#include <errno.h>
#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)
#define BUFFER_SIZE 1024

void set_nonblock(int fd){
    int flag = fcntl(fd,F_GETFL);
    if(flag == -1){
        perror("set_nonblock");
        exit(1);
    }
    flag |= O_NONBLOCK;
    if(fcntl(fd,F_SETFL, flag) < 0){
        perror("fcntl");
        exit(1);
    }
}

void test_01(){
    int listenfd;
    int on = 1;
    struct sockaddr_in server_addr;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,&on,sizeof(on)) < 0){
        perror("setsockopt");
        exit(-1);
    }
    DEBUG_INFO("begin bing");
    server_addr.sin_port = htons(9878);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
        perror("bind");
        exit(0);
    }
    listen(listenfd,5);

    set_nonblock(listenfd);
    int epfd = epoll_create(2);
    if(epfd < 0){
        perror("epoll_create");
        exit(-1);
    }
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD,listenfd, &ev);

    // int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
    #define MAX_EVENT_NUMBER 1
    struct epoll_event events[MAX_EVENT_NUMBER];
    char buf[BUFFER_SIZE];
    DEBUG_INFO("epoll_wait");
    while(1){
        int ret = epoll_wait(epfd, events,MAX_EVENT_NUMBER,-1);
        for(int i = 0;i < ret;i++){
            int sockfd = events[i].data.fd;
            if(events[i].events&EPOLLIN && sockfd == listenfd){
                struct sockaddr_in clientaddr;
                socklen_t addrlen = sizeof(clientaddr);
                int clientfd = accept(listenfd,(struct sockaddr*)&clientaddr,&addrlen);
                DEBUG_INFO("clientfd = %d",clientfd);
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = clientfd;
                epoll_ctl(epfd, EPOLL_CTL_ADD,clientfd, &ev);
                set_nonblock(clientfd);
            }else if(events[i].events&EPOLLIN){
                //memset(buf,0,sizeof(buf));
                bzero(buf,sizeof(buf));
                int index = 0;
                int readlen = 0;
                do{
                    readlen = recv(events[i].data.fd,&buf[index],1,0);
                    
                    if(readlen < 1){
                        DEBUG_INFO("readlen = %d",readlen);
                        break;
                    }else{
                        index++;
                    }
                }while(1);
                DEBUG_INFO("index = %d",index);
                int local_errno = errno;
                if(index > 0){
                    DEBUG_INFO("len = %d,buf = %s",index,buf);
                    int sendlen = send(sockfd,buf,index,0);
                    DEBUG_INFO("sendlen = %d",sendlen);
                }
                if(readlen == 0){
                    DEBUG_INFO("close %d",sockfd);
                    close(sockfd);
                    epoll_ctl(epfd, EPOLL_CTL_DEL,sockfd, &events[i]);
                }else if(readlen < 0){
                    if(local_errno == EINTR || local_errno == EWOULDBLOCK || local_errno == EAGAIN){
                        //
                        DEBUG_INFO("read finished");
                    }else{
                        perror("read");
                        DEBUG_INFO("close %d",sockfd);
                        close(sockfd);
                        epoll_ctl(epfd, EPOLL_CTL_DEL,sockfd, &events[i]);
                    }
                }                
            }else{
                DEBUG_INFO("unknown");
            }
        }
    }
    exit(0);
}

int main(int argc, char **argv)
{
    test_01();
}

CMakeLists.txt

project(mq_project)

cmake_minimum_required(VERSION 3.16)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
# set(CMAKE_C_COMPILER /arm-gcc/bin/arm-linux-gnueabihf-gcc)
# set(CMAKE_CXX_COMPILER /arm-gcc/bin/arm-linux-gnueabihf-g++)
# add_executable(test test.cpp)
# add_executable(test posix_thread.cpp)
add_executable(test epoll.cpp)

小结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于epoll的调试的几个问题 的相关文章

  • Linux epoll详解

    Linux epoll详解 一 什么是epoll epoll是什么 xff1f 按照man手册的说法 xff1a 是为处理大批量句柄而作了改进的poll 当然 xff0c 这不是2 6内核才有的 xff0c 它是在2 5 44内核中被引进的
  • epoll的LT模式(水平触发)和ET模式(边沿触发)

    文章目录 前言名称的记忆状态变化LT模式ET模式数据的读取和发送代码实践基础代码测试分类怎么解决ET触发了一次就不再触发了 总结 前言 epoll的触发模式是个引发讨论非常多的话题 xff0c 网络上这方面总结的文章也很多 xff0c 首先
  • 【Linux学习】epoll详解

    什么是 epoll epoll 是什么 xff1f 按照 man 手册的说法 xff1a 是为处理大批量句柄而作了改进的 poll 当然 xff0c 这不是 2 6 内核才有的 xff0c 它是在 2 5 44 内核中被引进的 epoll
  • select、poll、epoll简介

    select poll epoll都是IO多路复用机制 xff0c 都可实现同时监听多个I O事件的状态 xff0c 多路复用就是通过一种机制监视多个描述符 xff0c 一旦某个描述符读或者写就绪就能通知代码进行读写操作 本质他们都是同步I
  • netty使用epoll报错:java.lang.UnsatisfiedLinkError: failed to load the required native library

    Caused by java lang UnsatisfiedLinkError could not load a native library netty transport native epoll x86 64 最近修改moquett
  • close_on_exec选项:FD_CLOEXEC(fcntl)、O_CLOEXEC(open) 和 EPOLL_CLOEXEC(epoll_createl)

    close on exec解决的问题类型 我们经常会碰到一个进程需要fork出子进程的情况 而且子进程很可能会继续exec新的程序 这就不得不提到如何妥善处理好子进程中无用文件描述符的问题 fork函数的使用本不是这里讨论的话题 但必须提一
  • Linux-epoll机制

    主要接口 epoll create epoll ctl epoll wait epoll create 头文件 include
  • 谈谈Linux epoll惊群问题的原因和解决方案

    近期排查了一个问题 epoll惊群的问题 起初我并不认为这是惊群导致 因为从现象上看 只是体现了CPU不均衡 一共fork了20个Server进程 在请求负载中等的时候 有三四个Server进程呈现出比较高的CPU利用率 其余的Server
  • 基于升序链表的定时器及其简单应用

    Linux网络编程笔记 定时器 基于升序链表的定时器 这其实就是一个结点为 class util timer public util timer prev NULL next NULL 构造函数 public time t expire 任
  • python 图像处理(5):图像的批量处理

    有些时候 我们不仅要对一张图片进行处理 可能还会对一批图片处理 这时候 我们可以通过循环来执行处理 也可以调用程序自带的图片集合来处理 图片集合函数为 skimage io ImageCollection load pattern load
  • 一文明白IO模型和常问多路复用机制

    1 IO模型 Socket的输入操作有两步 wait for data 等待网络传输数据到达 到达后复制到内核缓冲区 copy data from kernel to user 把数据从内核缓冲区复制到应用进程缓冲区 涉及到两个对象 pro
  • 装上后这 14 个插件后,PyCharm 真的是无敌的存在

    来源 Python编程时光 作者 写代码的明哥 Key Promoter X 如果让我给新手推荐一个 PyCharm 必装插件 那一定是 Key Promoter X 它就相当于一个快捷键管理大师 它时刻地在 教导你 当下你的这个操作 应该
  • mac下面有epoll?

    没有的 但是mac下面有kqueue 跟epoll原理是差不多的 这个是没办法的 如果实在需要 就用Ubuntu吧 这个也可以无缝迁移 更多资源 更多文章由小白技术社提供 是我啦
  • 472-I/O阻塞和非阻塞,同步和异步

    阻塞 非阻塞 同步 异步 典型的一次I O的两个阶段是什么 数据准备 和 数据读写 我们作为服务器 接收客户端的请求 得先监听客户端有没有数据过来 这是一个状态 还有就是数据过来了该怎么去读写 这又是一个状态 实际上 阻塞 非阻塞 同步 异
  • Nginx 安装与部署配置以及Nginx和uWSGI开机自启

    下载 官方网站 https nginx org en download html Windows下安装 安装 下载后解压 切记不能含有中文路径 文件结构如图 我解压的路径就有中文 记得拷贝放置于英文目录下即可 启动 两种方法 1 直接双击该
  • 具有边缘触发事件的 epoll

    的手册页epoll有一个边缘触发的示例代码 如下所示 for nfds epoll wait epollfd events MAX EVENTS 1 if nfds 1 perror epoll pwait exit EXIT FAILUR
  • 使用 asyncio 时无法使用 os.fork() 将多个进程绑定到一个套接字服务器

    我们都知道 使用 asyncio 可以显着提高套接字服务器的性能 如果我们能够利用 cpu 中的所有核心 可能通过多处理模块或os fork etc 我现在正在尝试构建一个多核套接字服务器演示 其中一个异步套接字服务器侦听每个核心并全部绑定
  • epoll(epoll_wait等)可用于iOS吗?

    我正着手将一些现有的 POSIX 兼容代码移植到 iOS 据我所知 pthreads 可用 良好 但编译器未找到 iOS 上可以使用 epoll 吗 No epoll是 Linux 特定的系统调用 达尔文内核上最接近的等价物是kqueue
  • 边缘触发的 epoll 和 oneshot 只报告一次

    我目前正在添加从创建的 sockfdsaccept到具有以下事件的 epoll 实例 const int EVENTS EPOLLET EPOLLIN EPOLLRDHUP EPOLLONESHOT EPOLLERR EPOLLHUP 一旦
  • 有没有办法在 asyncio 构建的预分叉多进程 TCP 服务器上进行负载平衡?

    感谢之前回答的人 现在我可以构建一个多进程 TCP 服务器 每个进程分别运行一个异步服务器 但全部绑定到一个端口 使用 asyncio 时无法使用 os fork 将多个进程绑定到一个套接字服务器 https stackoverflow c

随机推荐

  • 向Python女神推荐这些年我追过的经典书籍

    最近 34 瑞丽模特学Python 34 的热点牵动了大江南北程序员的心 xff0c 有人说这是炒作 xff0c 也有人说这是推广Python的爆点 我嘿嘿一笑 xff0c 美女就是美女 xff0c 眼光那是杠杠的 xff0c 不仅人美 x
  • [gevent源码分析] 深度分析gevent运行流程

    一直对gevent运行流程比较模糊 xff0c 最近看源码略有所得 xff0c 不敢独享 xff0c 故分享之 gevent是一个高性能网络库 xff0c 底层是libevent xff0c 1 0版本之后是libev xff0c 核心是g
  • TCP服务器端和客户端程序设计

    一 实验目的 学习和掌握Linux下的TCP服务器基本原理和基本编程方法 体会TCP与UDP编程的不同 xff0c UDP编程 xff1a http blog csdn net yueguanghaidao article details
  • UDP服务器端和客户端程序设计

    实验三 UDP服务器端程序设计 一 实验目的 学习和掌握Linux下的UDP服务器基本原理和基本编程方法 xff0c 体会与TCP的区别 xff0c TCP编程 xff1a http blog csdn net yueguanghaidao
  • python实现的文本编辑器

    wxpython实现的文本编辑器 效果如下 xff1a 主要功能 xff1a 1 编辑保存文本 xff0c 打开修改文本 2 常用快捷键 xff0c 复制 xff0c 粘贴 xff0c 全选等 3 支持撤销功能 4 支持弹出式菜单 代码如下
  • C语言开发Linux下web服务器(支持GET/POST,SSL,目录显示等)

    这个主要是在CSAPP基础上做的 xff0c 添加了POST xff0c SSL xff0c 目录显示等功能 一 实现功能 xff1a 1 支持GET POST方法 2 支持SSL安全连接即HTTPS 3 支持CGI 4 基于IP地址和掩码
  • sklearn2pmml xgboost缺失值(missing)处理的坑

    sklearn2pmml xgboost缺失值 missing 处理的坑 今天同事在部署xgboost pmml模型时遇到了大坑 xff0c 线上spark预测和本地python预测结果怎么都不对应 xff0c 记录一下处理过程 看了下同事
  • adb导出手机应用到电脑

    简单说一下相关步骤 xff0c 以备不时之需 1 手机开启usb调试 2 Windows系统 Win 43 R打开命令行窗口 xff0c 输入adb devices xff0c 如果连接成功会出现机子的序列号 3 adb shell pm
  • Js作用域与作用域链详解

    一直对Js的作用域有点迷糊 xff0c 今天偶然读到Javascript权威指南 xff0c 立马被吸引住了 xff0c 写的真不错 我看的是第六版本 xff0c 相当的厚 xff0c 大概1000多页 xff0c Js博大精深 xff0c
  • windows10环境下tensorflow安装教程

    楼主最近一直忙着找工作 最近几个月一直all in java 好久没学机器学习 深度学习 前几天突然通知要提交论文中期了 于是赶紧打开电脑 结果发现之前安装的tensorflow居然登陆不上了 折腾了半天 搜过各种csdn博客 一直安装失败
  • 'gbk' codec can't encode character '\xa0'

    从网上抓了一些字节流 xff0c 想打印出来结果发生了一下错误 xff1a UnicodeEncodeError 39 gbk 39 codec can 39 t encode character 39 xbb 39 in position
  • 【Git记录学习】github创建项目以及本地使用(vscode)

    一 github创建空仓库 从github中创建空仓库 在执行完上一步操作后会返回这样的界面 xff0c 包括了一些基本的git操作以及HttpS SSH地址 生成一个readme md文档 xff08 步骤2 Set up下面有蓝色的超链
  • 关于DFT变换含义、公式和具体形式

    原文地址 xff1a http blog sina com cn s blog 7853c3910102v9wd html 这篇文章从实际工程应用的角度 xff0c 记录一下如何计算 xff0c 关于公式 变形和应用 维基百科上的 DFT公
  • 1602显示数字不稳定一直跳动(AD转换)

    程序如下所示 首先说明下 xff0c 此程序为AD转换芯片PCF8591采集电压数据 xff0c 然后送到1602显示 现象 xff1a 1602显示的数字一直频繁的跳动 xff0c 乱花眼 此现象不是一直出现的 xff0c 有时候会出现
  • C++11中的线程类

    前面介绍的线程是利用了POSIX线程库 xff0c 这是传统C C 43 43 程序员使用线程的方式 xff0c 而C 43 43 11提供了语言层面使用线程的方式 C 43 43 11新标准中引入了5个头文件来支持多线程编程 xff0c
  • 4.4.1内核编译

    内核源码下载地址 xff1a https mirrors edge kernel org pub linux kernel v4 x linux 4 4 1 tar gz 安装依赖包 xff1a 报错就装 cp boot config xx
  • fatal error: hugetlbfs.h: No such file or directory

    fatal error hugetlbfs h No such file or directory 解决办法 xff1a sudo apt get update sudo apt get install libhugetlbfs dev
  • WSL下 配置NFS-失败

    配置一个IP地址 xff1a sudo ip addr add 192 168 250 2 24 broadcast 192 168 250 255 dev eth2 sudo apt get install nfs kernel serv
  • OMT 对象模型、动态模型和功能模型

    对象模型描述系统中对象的静态结构 对象之间的关系 对象的属性 对象的操作 对象模型表示静态的 结构上的 系统的 数据 34 特征 对象模型为动态模型和功能模型提供了基本的框架 xff0c 对象模型用包含对象和类的对象图来表示 OMT的对象模
  • 关于epoll的调试的几个问题

    将今天调试的几个小问题点总结下 xff0c 后续遇到再添加 一 将总结的问题点放在最前面 1 epoll wait的maxevents参数 epoll wait的maxevents参数 xff0c 经过测试 xff0c maxevents的