C++高性能通信:了解Iceoryx与零拷贝技术的实现与应用

文章目录

    • 0. 引言
    • 1. Iceoryx使用到的零拷贝技术
      • 1.1 零拷贝技术概述
      • 1.2 零拷贝的优势
      • 1.3 Iceoryx零拷贝的实现
      • 1.4 信息轮询与信号触发
    • 2. Iceoryx的核心概念
    • 3. Iceoryx使用示例
      • 3.1 发布者程序
      • 3.2 订阅者程序
      • 3.3 编译和运行
      • 3.4 压力测试脚本
    • 4. 参考文章

0. 引言

Iceoryx是一个开源的实时通信框架,特别适用于需要高性能和低延迟的嵌入式系统,如自动驾驶系统、机器人控制、航空航天等。

详细介绍请看官网

img

iceoryx 使用真正的零拷贝共享内存方法,允许将数据从发布者传输到订阅者而无需任何副本。这可确保数据传输具有恒定的延迟,无论有效负载的大小是多少。

img

1. Iceoryx使用到的零拷贝技术

1.1 零拷贝技术概述

零拷贝是指在数据传输过程中,避免不必要的数据拷贝操作。传统的数据传输通常涉及将数据从一个缓冲区复制到另一个缓冲区,这会产生额外的开销。而零拷贝技术允许数据在不进行拷贝的情况下直接传递到目标缓冲区,从而提高传输效率。

Iceoryx使用共享内存进行进程间通信,将数据放置在共享内存区域,然后通过指针引用实现数据传递,避免了数据的额外复制。

1.2 零拷贝的优势

  1. 减少CPU开销:零拷贝减少了CPU的复制操作,提高了系统性能。
  2. 降低内存占用:由于数据不需要在不同缓冲区之间复制,内存使用更为高效。
  3. 降低传输延迟:数据直接传递,无需复制等待时间。

1.3 Iceoryx零拷贝的实现

Iceoryx通过以下方式实现真正的零拷贝:

  • 利用共享内存技术,预先开辟内存块(chunk),publisher将数据写入。
  • Subscriber通过指针获取chunk中的信息,数据被写入时,subscriber收到一个指针。
  • Iceoryx维护每个chunk的引用记录,确保资源不被浪费。

1.4 信息轮询与信号触发

为了提升数据获取效率,Iceoryx提供两种方式:

  • WaitSet:采用react设计模式,绑定对应的subscribers,数据到来时触发通知。
  • Listener:直接触发用户定制的callback,数据到来时调用回调函数。

2. Iceoryx的核心概念

掌握以下核心概念可以帮助进行Iceoryx的基本通信功能开发:

  • RouDi:Iceoryx的守护进程,不同应用需要与之连接才能正常通信。运行Iceoryx程序前需先启动RouDi。

    iox-roudi
    
  • Runtime:每个应用在Iceoryx框架下运行时需要初始化其runtime。

    constexpr char APP_NAME[] = "iox-publisher";
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);
    
  • Publisher*:数据发送器,需要绑定topic使用。

    iox::popo::Publisher<Data> publisher({"Group", "Topic", "Instance"});
    
  • Subscriber:数据接收器,需要绑定topic使用。

    iox::popo::Subscriber<Data> subscriber({"Group", "Topic", "Instance"});
    
  • Topic:数据载体,Publisher发送一个Topic,Subscriber接收相应的Topic。

3. Iceoryx使用示例

3.1 发布者程序

#include "iceoryx_posh/popo/publisher.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
#include <chrono>
#include <thread>
#include <iostream>struct Data {char message[128];
};int main() {constexpr char APP_NAME[] = "iox-publisher";iox::runtime::PoshRuntime::initRuntime(APP_NAME);iox::popo::Publisher<Data> publisher({"Group", "Topic", "Instance"});while (true) {publisher.loan().and_then([&](auto& sample) {std::strcpy(sample->message, "Hello from Publisher");sample.publish();}).or_else([](auto& error) {std::cerr << "Loaning sample failed: " << error << std::endl;});std::this_thread::sleep_for(std::chrono::milliseconds(1000));}return 0;
}

3.2 订阅者程序

#include "iceoryx_posh/popo/subscriber.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
#include <chrono>
#include <thread>
#include <iostream>struct Data {char message[128];
};int main() {constexpr char APP_NAME[] = "iox-subscriber";iox::runtime::PoshRuntime::initRuntime(APP_NAME);iox::popo::Subscriber<Data> subscriber({"Group", "Topic", "Instance"});while (true) {subscriber.take().and_then([&](const auto& sample) {std::cout << "Received: " << sample->message << std::endl;}).or_else([](auto& error) {if (error != iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE) {std::cerr << "Taking sample failed: " << error << std::endl;}});std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

3.3 编译和运行

确保已安装Iceoryx,并正确配置CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(IceoryxPubSub)set(CMAKE_CXX_STANDARD 14)
find_package(iceoryx_posh REQUIRED)add_executable(publisher_iceoryx publisher_iceoryx.cpp)
target_link_libraries(publisher_iceoryx iceoryx_posh::iceoryx_posh iceoryx_posh::iceoryx_posh_roudi_environment)add_executable(subscriber_iceoryx subscriber_iceoryx.cpp)
target_link_libraries(subscriber_iceoryx iceoryx_posh::iceoryx_posh iceoryx_posh::iceoryx_posh_roudi_environment)

然后在项目根目录创建并运行CMake:

mkdir build
cd build
cmake ..
make

运行RouDi(Iceoryx的守护进程):

iox-roudi &

运行发布者和订阅者程序:

./publisher_iceoryx &
./subscriber_iceoryx &

3.4 压力测试脚本

#include <thread>
#include <vector>
#include <cstdlib>void run_publisher() {system("./publisher_iceoryx");
}void run_subscriber() {system("./subscriber_iceoryx");
}int main() {const int num_publishers = 10;const int num_subscribers = 10;std::vector<std::thread> threads;for (int i = 0; i < num_publishers; ++i) {threads.emplace_back(run_publisher);}for (int i = 0; i < num_subscribers; ++i) {threads.emplace_back(run_subscriber);}for (auto& t : threads) {t.join();}return 0;
}

4. 参考文章

iceoryx源码阅读
iceoryx_github

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星环科技携手东华软件推出一表通报送联合解决方案

随着国家金融监督管理总局“一表通”试点工作的持续推进&#xff0c;星环科技携手东华软件推出了基于星环科技分布式分析型数据库ArgoDB和大数据基础平台TDH的一表通报送联合解决方案&#xff0c;并已在多地实施落地中得到充分验证。 星环科技与东华软件作为战略合作伙伴&…

深度学习复盘与论文复现E

文章目录 一、项目复现的问题及其解决方案1、 Cannot find DGL C graphbolt library2、 “is“ with a literal. Did you mean ““?”3、运行SEG、SPG查看GATNet的网络结构4、关于LI-FPN项目找不到数据粒度不匹配问题5、关于LI-FPN项目num_samples为空6、解决路径问题7、 !ss…

Java | Leetcode Java题解之第273题整数转换英文表示

题目&#xff1a; 题解&#xff1a; class Solution {String[] singles {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};String[] t…

PHP基础语法(四)

一、字符串类型 1、字符串定义语法 1&#xff09;单引号字符串&#xff1a;在单引号内部&#xff0c;所有的字符都会按照字面意义解释&#xff0c;不会进行变量替换或转义处理&#xff0c;除了 \ 表示单引号本身。 $str1 Hello, World!;2&#xff09;双引号字符串&#xff…

数据库——单表查询

一、建立数据库mydb8_worker mysql> use mydb8_worker; 二、建立表 1.创建表 mysql> create table t_worker(department_id int(11) not null comment 部门号,-> worder_id int(11) primary key not null comment 职工号,-> worker_date date not null comment…

qt SQLite学习记录

1. 查看qt中数据库的驱动的类型的支持 QStringList drivers QSqlDatabase::drivers();//获取qt中所支持的数据库驱动类型foreach(QString driver,drivers){qDebug()<<driver;}2. Qt SQL 模块包含的主要类的功能介绍 Qt SQL 模块包含了一些主要的类&#xff0c;用于在 …

传输层协议——TCP

TCP协议 TCP全称为“传输控制协议”&#xff0c;要对数据的传输进行一个详细的控制。 特点 面向连接的可靠性字节流 TCP的协议段格式 源/目的端口&#xff1a;表示数据从哪个进程来&#xff0c;到哪个进程4位首部长度&#xff1a;表示该TCP头部有多少字节&#xff08;注意它…

大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

SQL注入万字详解,基于sqli-labs(手注+sqlmap)

目录 一、什么是SQL 1.什么是SQL 2.SQL的作用 3.MySQL基础知识 4.SQL增、删、改语句 *5.SQL查询语句 二、什么是SQL注入 1.SQL注入原理&#xff1a; 2.SQL注入&#xff1a; 3.SQL注入危害&#xff1a; 4.SQL注入技术分类&#xff1a; 5.防御方法&#xff1a;使用参…

javaEE-01-tomcat

文章目录 javaWebTomcat启动 Tomcat 服务器测试服务器是否成功停止tomcat服务器修改服务器的端口号 Idea整合tomcat服务器 javaWeb 所有通过 Java 语言编写可以通过浏览器访问的程序的总称,是基于请求和响应来开发的。 请求: 客户端给服务器发送数据(Request)响应: 服务器给客…

萝卜快跑:自动驾驶的先锋与挑战

萝卜快跑&#xff1a;自动驾驶的先锋与挑战 近段时间&#xff0c;由萝卜快跑引发的自动驾驶事件如火如荼&#xff0c;成为科技领域的热门话题。萝卜快跑作为自动驾驶领域的重要参与者&#xff0c;其最新事件引发了广泛的关注和讨论。 萝卜快跑是百度推出的自动驾驶出行服务平台…

Pytorch使用教学2-Tensor的维度

在PyTorch使用的过程中&#xff0c;维度转换一定少不了。而PyTorch中有多种维度形变的方法&#xff0c;我们该在什么场景下使用什么方法呢&#xff1f; 本小节我们使用的张量如下&#xff1a; # 一维向量 t1 torch.tensor((1, 2)) # 二维向量 t2 torch.tensor([[1, 2, 3], …

common-intellisense:助力TinyVue 组件书写体验更丝滑

本文由体验技术团队Kagol原创~ 前两天&#xff0c;common-intellisense 开源项目的作者 Simon-He95 在 VueConf 2024 群里发了一个重磅消息&#xff1a; common-intellisense 支持 TinyVue 组件库啦&#xff01; common-intellisense 插件能够提供超级强大的智能提示功能&…

Java设计模式—单例模式(Singleton Pattern)

目录 一、定义 二、应用场景 三、具体实现 示例一 示例二 四、懒汉与饿汉 饿汉模式 懒汉模式 五、总结 六、说明 一、定义 二、应用场景 ‌单例模式的应用场景主要包括以下几个方面&#xff1a; ‌日志系统&#xff1a;在应用程序中&#xff0c;通常只需要一个日…

【JS逆向课件:第十三课:异步爬虫】

回顾 并行和并发 表示程序/计算机具有处理多个任务的能力 并行表示可以同时处理多个任务&#xff08;几个多核CPU&#xff09;并发无法同时处理多个任务&#xff0c;但是可以基于时间片轮转法在多任务间快速切换的执行任务。 同步和异步 在基于并行或者并发处理任务的时候&am…

链式法则和自动求导

向量链式法则 说明&#xff1a; 1.第一个式子&#xff0c; y是标量&#xff0c;u是标量&#xff0c;x是n维向量 2.第二个式子&#xff0c;y是标量&#xff0c;u是k维向量&#xff0c;x是n维向量&#xff0c;所以y对u求导是k维的行向量&#xff0c;u对x求导是k行n列的矩阵&…

学术研讨 | 区块链治理与应用创新研讨会顺利召开

学术研讨 近日&#xff0c;国家区块链技术创新中心组织&#xff0c;长安链开源社区支持的“区块链治理与应用创新研讨会”顺利召开&#xff0c;会议围绕区块链治理全球发展现状、研究基础、发展趋势以及区块链行业应用创新展开研讨。北京大学陈钟教授做了“区块链治理与应用创…

ESP32-S3-DevKitC-1开发记录帖——与MPU6050进行姿态检测

目录 MPU6050传感器——姿态检测 1.姿态检测 1.1 基本认识 1&#xff09;坐标系 2&#xff09;姿态角的关系 3&#xff09;陀螺仪检测的缺陷 4&#xff09;利用加速度计检测角度 5&#xff09;利用磁场检测角度 1.2 姿态融合与四元数 1.3传感器工作原理 1.4 MPU6050模…

【PyTorch】图像多分类项目

【PyTorch】图像二分类项目 【PyTorch】图像二分类项目-部署 【PyTorch】图像多分类项目 【PyTorch】图像多分类项目部署 多类图像分类的目标是为一组固定类别中的图像分配标签。 目录 加载和处理数据 搭建模型 定义损失函数 定义优化器 训练和迁移学习 用随机权重进行训…

one-api 源码调试配置

本文主要介绍通过 VSCode 调试 one-api 源码。 一、环境配置 1.1 VSCode 和 one-api 安装 首先,确保已经安装了 VSCode(下载链接)和 one-api 源码(下载链接)已下载并安装了依赖 1.2 安装 Go 插件 在 VSCode 中,安装 Go 插件。 1.3 安装 dlv 调试包 可以通过下载源码…