nng协议nni_posix_pollq_create(nni_posix_pollq *pq) 初始化

1.基本概念

        epoll 是 Linux 内核提供的一种高效的 I/O 事件通知机制,适用于监视多个文件描述符,以便在这些文件描述符上发生 I/O 事件时能够立即得到通知。epoll 的工作方式比传统的 select 和 poll 更加高效,尤其适合处理大量并发连接的场景。

        epoll实例是由epoll_create 或 epoll_create1 创建的,它本质上是一个内核对象,用来跟踪和管理一组文件描述符的事件。创建epoll 实例时,会返回一个文件描述符,这个文件描述符用与后续的epoll操作。

2. 文件描述符(file descriptors)

在epoll中,文件描述符可以是任何支持非阻塞I/O的文件描述符,如套接字、管道、文件等。

可以通过  epoll_ctl  函数将这些文件描述符添加到epoll实例中,以监视它们上的事件。

3.事件:

        epoll 支持监视多种事件,如 读事件(EPOLLIN)、写事件(EPOLLOUT)、错误事件等。

事件通过 structure epoll_event 结构体来描述。

4. epoll 的基本使用流程

        4.1 创建epoll 实例

使用epoll_create  或 epoll_create1 创建一个epoll实例。返回的文件描述符用于标识这个实例。

int  epfd = epoll_create1(EPOLL_CLOEXEC);
if(epfd < 0){
    perror("epoll_create1");
    return -1;
}

        4.2 添加、修改或删除文件描述符:

使用epoll_ctl 函数添加(EPOLL_CTL_ADD)、修改(EPOLL_CTL_MOD)或 删除(EPOLL_CTL_DEL)要监视的文件描述符。

struct epoll_event ev;
ev.events = EPOLLIN;  // 监视读事件
ev.data.fd = fd;      // 需要监视的文件描述符

if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0){
    perror("epoll_ctl");
    return -1;
}

        4.3 等待事件

使用epoll_wait 来等待文件描述符上的事件。该函数会阻塞直到一个或多个事件发生,或者超时。

struct epoll_event events[MAX_EVENTS];
int nfds = epoll_wait(epfd, events, MAX_EVENTS, -1); // epoll 等待超时,也就是没有等到集合中文件描述符上发生指定的事件,将返回 0;
if(nfds < 0){
    perror("epoll_wait");
    return -1;
}

for(int i=0; i < nfds; ++i){
    if(events[i].events & EPOLLIN){
        //处理读事件
    }

    if(events[i].events & EPOLLOUT){
        //处理写事件
    }

    //  处理其他事件,或许有错误发生
}

5. 代码分析【正文】

        5.1 函数说明

static int nni_posix_pollq_create(nni_posix_pollq *pq)

        这段代码的功能是创建一个文件描述符,并将其添加到 epoll 实例中,以便在程序需要自我唤醒时,能够使用该文件描述符触发  epoll  事件。 主要步骤包括创建事件文件描述符,设置文件描述符属性、 配置  epoll 事件并将其添加到  epoll  实例中。详细信息如下:

if((pq->epfd = epoll_create1(EPOLL_CLOEXEC) < 0){
    return (nni_plat_erron(errno))
}

这段代码的作用是创建一个epoll  实例并将文件描述符存储在 pq 结构体的 epfd  中。 参数EPOLL_CLOEXEC 的表示在执行exec系列函数时,自动关闭这个文件描述符。(请自行参考exec系列函数,exit...)。

        5.2  nni_posix_pollq_add_eventfd(pq)

        在nni_posix_pollq_create(nni_posix_pollq  *pq)中调用了 nni_posix_pollq_add_eventfd(pq)这个函数。

        1.  定义epoll_event   ev

         2. 创建事件文件描述符, 使用eventfd 函数创建一个文件描述符  fd, 初始值唯0 , 标志为EFD_NONBLOCK (非阻塞)

if((fd = eventfd(0, EFD_NONBLOCK) < 0 ){
    return (nni_plat_errno(errno));
}

        3. 设置文件描述符属性

(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
(void) fcntl(fd, F_SETFL, O_NONBLOCK);

使用fcntl 设置文件描述符的标志,FD_CLOEXEC,使其在执行exec()系列函数后关闭。

再次使用fcntl 函数设置文件描述符为非阻塞模式。

        4. 设置 epoll 事件

ev.events = EPOLLIN;
ev.data.ptr = 0;

设置 epoll 事件唯   EPOLLIN,表示监听读事件。 将ev.data.ptr 设置为 0, 这个指针可以用来存储用户数据,此处设置为0. 

        5. 向  epoll  实例中添加事件。

if(epoll_ctl(pq->epfd, EPOLL_CTL_ADD, fd, &ev) != 0){
    (void) close(fd);
    return (nni_plat_errno(errno);
}

         6. 保存文件描述符并返回成功

       将文件描述符  fd  保存到pq结构体的evfd 字段中。并返回成功。

pq->evfd  = fd;
return (0);

总结一下就是:这段代码的功能是创建一个事件文件描述符,并将其添加到 epoll 实例中,以便在程序需要自我唤醒时能够使用该文件描述符触发 epoll 事件。主要步骤包括创建事件文件描述符、设置文件描述符属性、配置 epoll 事件并将其添加到 epoll 实例中。

6.  nni_thr_init(&pq->thr, nni_posix_poll_thr, pq) 初始化

(待续)

7. 设置 pq->thr名称 

8. 执行nni_thr_run函数

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值