【C语言】RDMACM、Verbs API与epoll一起使用的示例

一、epoll介绍

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

以下是epoll的主要使用方法和优点:

  1. epoll的创建和使用主要涉及到三个函数:epoll_create、epoll_ctl和epoll_wait。首先,使用epoll_create创建一个新的epoll实例,并返回一个引用该实例的文件描述符。然后,通过epoll_ctl注册对感兴趣的文件描述符。最后,使用epoll_wait等待I/O事件。
  2. epoll的优点主要体现在:支持一个进程打开大数目的socket描述符(FD);IO效率不随FD数目增加而线性下降;支持边缘触发模式;使用mmap加速内核与用户空间的消息传递。
  3. 水平触发和边沿触发是epoll的两种事件分发机制。二者的区别在于,水平触发模式下,只要文件描述符处于就绪状态,无论应用程序是否读取或者写入数据,每次调用epoll_wait都会返回该文件描述符;而在边缘触发模式下,只有当文件描述符状态发生变化时(比如从非就绪变为就绪),epoll_wait才会返回该文件描述符。

总的来说,epoll是Linux内核中处理大批量文件描述符的高效工具,特别适用于大量并发连接中只有少量活跃的情况,能显著提高系统CPU利用率。

二、示例

以下是一个使用C语言的示例,展示了如何在使用RDMACM和Verbs API时与epoll一起使用:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <rdma/rdma_cma.h>

#define MAX_EVENTS 10

struct connection {
    struct rdma_cm_id *id;
    struct ibv_qp *qp;
    // 其他连接相关的数据
};

void handle_cm_event(struct rdma_cm_event *event) {
    // 处理RDMACM事件的逻辑
}

void handle_cq_event(struct ibv_wc *wc) {
    // 处理完成队列事件的逻辑
}

int main() {
    struct rdma_event_channel *cm_channel;
    struct rdma_cm_event *event;
    struct epoll_event epoll_events[MAX_EVENTS];
    struct connection *conn;
    struct ibv_cq *cq;
    struct ibv_wc wc;
    int cm_fd, cq_fd, epoll_fd, i, n;

    // 创建RDMACM事件通知文件描述符
    cm_channel = rdma_create_event_channel();
    if (!cm_channel) {
        perror("Failed to create RDMACM event channel");
        return 1;
    }

    // 创建完成队列(CQ)
    cq = ibv_create_cq(NULL, 10, NULL, NULL, 0);
    if (!cq) {
        perror("Failed to create completion queue");
        return 1;
    }

    // 获取RDMACM事件通知文件描述符和完成队列的文件描述符
    cm_fd = rdma_event_channel_fd(cm_channel);
    cq_fd = cq->channel->fd;

    // 创建epoll实例
    epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        perror("Failed to create epoll instance");
        return 1;
    }

    // 将RDMACM事件通知文件描述符添加到epoll的事件集合中
    struct epoll_event cm_event;
    cm_event.events = EPOLLIN | EPOLLET;
    cm_event.data.fd = cm_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, cm_fd, &cm_event) == -1) {
        perror("Failed to add RDMACM event channel to epoll");
        return 1;
    }

    // 将完成队列的文件描述符添加到epoll的事件集合中
    struct epoll_event cq_event;
    cq_event.events = EPOLLIN | EPOLLET;
    cq_event.data.fd = cq_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, cq_fd, &cq_event) == -1) {
        perror("Failed to add completion queue to epoll");
        return 1;
    }

    // 进入事件循环
    while (1) {
        // 等待事件发生
        n = epoll_wait(epoll_fd, epoll_events, MAX_EVENTS, -1);
        if (n == -1) {
            perror("Failed to wait for events");
            return 1;
        }

        // 处理所有事件
        for (i = 0; i < n; i++) {
            if (epoll_events[i].data.fd == cm_fd) {
                // 有RDMACM事件发生
                event = rdma_get_cm_event(cm_channel);
                handle_cm_event(event);
                rdma_ack_cm_event(event);
            } else if (epoll_events[i].data.fd == cq_fd) {
                // 有完成队列事件发生
                while (ibv_poll_cq(cq, 1, &wc) > 0) {
                    handle_cq_event(&wc);
                }
            }
        }
    }

    // 清理资源
    close(epoll_fd);
    ibv_destroy_cq(cq);
    rdma_destroy_event_channel(cm_channel);

    return 0;

}

在这个示例中,我们使用了rdma/rdma_cma.h头文件中提供的RDMACM和Verbs API。首先,我们创建了一个RDMACM事件通知文件描述符和一个完成队列(CQ),然后将它们的文件描述符添加到epoll的事件集合中。接下来,我们进入一个事件循环,等待事件发生。如果有RDMACM事件发生,我们调用handle_cm_event函数来处理该事件;如果有完成队列事件发生,我们调用handle_cq_event函数来处理该事件。
请注意,这只是一个简单的示例,实际使用时可能需要根据具体需求进行更多的处理和错误检查。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/241578.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python】多任务编程

python多任务编程 有哪些编程提速的方法 单线程串行&#xff1a;不加改造的程序 多线程并发&#xff1a;利用CPU和IO可以同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成 多CPU并行/多进程&#xff1a;利用多核CPU的能力&#xff0c;真正的并行执行任务 多机器并行&#…

快速学习Java Agent

1.1 java agent原理 我们知道&#xff0c;要使用Skywalking去监控服务&#xff0c;需要在其 VM 参数中添加 “- javaagent:/usr/local/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar"。这里就 使用到了java agent技术。 Java agent 是什么&#xff…

python tkiinter中滑块的使用

需求&#xff1a;需要在Canvas组件上添加滑块功能 解决&#xff1a;使用tkinter提供的Scrollbar组件&#xff0c;由于没发现直接在画布上显示滑块功能的方法&#xff0c;所以后面采用在显示画布的容器上显示滑块&#xff0c;并绑定到画布上。 具体案例demo&#xff1a; from t…

视频滤波驱动器电路D1671 D1675的性能描述和分析

D1671四阶标清视频滤波器驱动&#xff0c;1CH&#xff0c;工作电压2.8V~5.5V&#xff0c;转换速率40V/s D1675六阶高清视频滤波器驱动&#xff0c;1CH&#xff0c;工作电压2.5V~5.5V&#xff0c;转换速率400V/s

02鸿蒙APP真机运行及证书签名打包

目录 1、真机运行1.1、运行安装错误1.2、解决方案&#xff1a;第一步&#xff1a;安装兼容真机的sdk版本2.2.0&#xff08;API6&#xff09;&#xff0c;如下图所示&#xff1a;第二步&#xff1a;新建一个API6的工程项目第三步&#xff1a;运行API6创建的工程项目第四步&#…

如何提高嵌入式软件工程师的技术深度?

今日话题&#xff0c;如何提高嵌入式软件工程师的技术深度&#xff1f;建立坚实的基础知识是深入研究的关键。只有深入理解基础知识&#xff0c;才能在理论指导下不断深化和扩展自己的技术。没有坚实的基础&#xff0c;深入研究就显得空中楼阁。如果你有兴趣进入嵌入式行业我可…

数据库——安全性

智能2112杨阳 一、目的与要求&#xff1a; 1、设计用户子模式 2、根据实际需要创建用户角色及用户&#xff0c;并授权 3、针对不同级别的用户定义不同的视图&#xff0c;以保证系统的安全性 二、内容&#xff1a; 先创建四类用户角色&#xff1a; 管理员角色Cusm、客户角…

初级数据结构(三)——栈

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;二&#xff09;——链表 | 初级数据结构&#xff08;四&#xff09;——队列 下一篇-> 1、栈的特性 1.1、函数栈帧简述 即使是刚入门几天的小白&#xff0c;对栈这个字…

Linux——MySQL数据库系统()

一、访问MySQL数据库 MySQL数据库系统也是一个典型的C/S(客户端/服务器&#xff09;架构的应用&#xff0c;要访问MySQL数据库需要使用专门的客户端软件。在Linux系统中&#xff0c;最简单、易用的MySQL客户端软件是其自带的mysql命令工具。 1、登录到MySQL服务器经过安装后的初…

深入理解TheadLocal的使用场景和注意事项

前言 在日常实际开发当中我们往往会看到项目中有使用 ThreadLocal 的场景&#xff0c;大多数人有时候可能涉及不到自己的业务则没有进行关注。通常我在看代码时对于一些未知的东西常常引起我的好奇&#xff0c;我往往会分析&#xff1a;为什么要这么做&#xff1f;好处是什么&…

一文看懂支付前链路流程

一文看懂支付前链路流程 前序 首先支付流程讲究的就是快&#xff0c;还有就是订单的冲入&#xff0c;我们不能说一笔交易订单进来都加一个分布式锁去解决&#xff0c;所以我们目前常用的做法就是一个订单进来&#xff0c;首先落库&#xff0c;如果落库失败&#xff0c;并且是…

用XAMPP在Windows系统构建一个本地Web服务器

用XAMPP在Windows系统构建一个本地Web服务器 Build a Local Web Server for Windows with XAMPP By JacksonML 本文简要介绍如何获取和安装XAMPP以实现Windows环境下本地Web服务器的过程&#xff0c;希望对广大网友和学生有所帮助。 所谓本地Web服务器&#xff0c;即使用本地…

UML-认识6种箭头(画类图无烦恼)

文章目录 一、背景二、箭头详解2.1 泛化&#xff08;Generalization&#xff09;2.2 实现&#xff08;Realize&#xff09;2.3 依赖&#xff08;Dependency&#xff09;2.4 关联&#xff08;Association&#xff09;2.5 聚合&#xff08;Aggregation&#xff09;2.6 组合&#…

24V降12V2A同步降压芯片WT6023A

24V降12V2A同步降压芯片WT6023A 今天给大家带来一款高性能的DC/DC转换器WT6023A&#xff0c;快来一起了解一下吧&#xff01; WT6023A是一款采用抖动频率模式控制架构的高效、单片同步降压型DC/DC转换器&#xff0c;能够提供高达6A的连续负载&#xff0c;具有出色的线路和负载…

BugKu-Web-Flask_FileUpload(模板注入与文件上传)

Flask Flask是一个使用Python编写的轻量级Web应用框架。它是一个微型框架&#xff0c;因为它的核心非常简单&#xff0c;但可以通过扩展来增加其他功能。Flask的核心组件包括Werkzeug&#xff0c;一个WSGI工具箱&#xff0c;以及Jinja2&#xff0c;一个模板引擎。 Flask使用BSD…

快速准确翻译文件夹名:英文翻译成中文,文件夹批量重命名的技巧

在处理大量文件夹时&#xff0c;可能会遇到要将英文文件夹名翻译成中文的情况。同时也可能要批量重命名这些文件夹。今天一起来看下云炫文件管理器如何快速准确翻译文件夹名&#xff0c;进行批量重命名的技巧。 下图是文件夹名翻译前后的效果图。 英文文件夹名批量翻译成中文…

注意力机制和自注意力机制

有很多自己的理解&#xff0c;仅供参考 Attention注意力机制 对于一张图片&#xff0c;我们第一眼看上去&#xff0c;眼睛会首先注意到一些重点的区域&#xff0c;因为这些区域可能包含更多或更重要的信息&#xff0c;这就是注意力机制&#xff0c;我们会把我们的焦点聚焦在比…

2023年12月7日:QT实现登陆界面

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//窗口设置this->resize(600,500);//重新设置窗口大小this->setWindowTitle("QQ-盗版");//设置窗口名为QQ-盗版this->setWindowIcon(QIcon("D:\\Qt\\funny\\pi…

【改进YOLOv8】融合感受野注意力卷积RFCBAMConv的杂草分割系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 随着计算机视觉技术的不断发展&#xff0c;图像分割成为了一个重要的研究领域。图像分割可以将图像中的不同对象或区域进行有效的分离&#xff0c;对于许多应用领…

【广州华锐视点】仓储物流3D数字孪生平台打造更高效、智能的物流管理体验

在当今快速发展的物流行业中&#xff0c;传统的管理和监控方法往往难以满足复杂运营的需求。为了解决这个问题&#xff0c;广州华锐互动提供仓储物流3D数字孪生平台定制开发服务&#xff0c;打造更为高效、智能的物流管理体验。 仓储物流3D数字孪生平台是一种基于虚拟现实技术的…