6.4 共享内存传输

共享内存(SHM)传输依靠主机操作系统提供的共享内存机制,实现了在同一处理单元/机器上运行的实体之间的快速通信。

注意
Fast DDS 利用域参与者(DomainParticipant)的 GuidPrefix_t 来识别在同一主机上运行的对等方。GuidPrefix_t 的前 4 个字节相同的两个参与者被视为在同一主机上运行。提供了 is_on_same_host_as() API 来检查此条件。此外,还请考虑进程内传输的 GUID 前缀注意事项中包含的警告。

共享内存传输比 UDP / TCP 等其他网络传输提供更好的性能,即使这些传输使用环回接口也是如此。这主要是由于以下原因:

  • 大型消息支持:网络协议需要对数据进行分片,以符合特定协议和网络栈的要求,从而增加了通信开销。共享内存传输允许复制完整消息,其唯一的大小限制是机器的内存容量。
  • 减少内存复制次数:当向不同的端点发送相同的消息时,共享内存传输可以直接与所有目标端点共享相同的内存缓冲区。其他协议需要为每个端点执行一次消息复制。
  • 更少的操作系统开销:初始设置完成后,共享内存传输所需的系统调用比其他协议少得多。因此,使用共享内存可以提高性能/减少时间消耗。

6.4.1 概念定义

本节描述基本概念,以帮助解释共享内存传输如何将数据消息传递到适当的域参与者。其目的不是成为实现的详尽参考,而是对每个概念进行全面解释,以便用户可以根据自己的需求配置传输。

本节中的许多描述将按照下图所示的示例用例进行,其中参与者 1 向参与者 2 发送数据消息。请在理解定义时参考该图。
在这里插入图片描述

共享内存传输的序列图

6.4.1.1 段(Segment)

段是可以从不同进程访问的一块共享内存。每个配置了共享内存传输的域参与者都会创建一个共享内存段。域参与者将需要传递给其他域参与者的任何数据写入此段,远程域参与者能够使用共享内存机制直接读取这些数据。

注意
使用具有更高权限的用户(例如 root)启动任何进程都可能导致通信问题,因为非特权用户运行的进程可能无法写入内存段。

每个段都有一个 segmentId,这是一个 16 字符的 UUID,用于唯一标识每个共享内存段。这些 segmentId 用于识别和访问每个域参与者的段。

6.4.1.2 段缓冲区(Segment Buffer)

在共享内存段中分配的缓冲区。它充当放置在段中的 DDS 消息的容器。换句话说,域参与者在段上写入的每条消息都将放在不同的缓冲区中。

6.4.1.3 缓冲区描述符(Buffer Descriptor)

它充当指向特定段中特定段缓冲区的指针。它包含 segmentId 和段缓冲区相对于段基址的偏移量。在与其他域参与者通信消息时,共享内存传输仅分发缓冲区描述符,避免了消息从一个域参与者复制到另一个域参与者。通过此描述符,接收域参与者可以访问写入缓冲区中的消息,因为它唯一地标识了段(通过 segmentId)和段缓冲区(通过其偏移量)。

6.4.1.4 端口(Port)

表示用于通信缓冲区描述符的通道。它在共享内存中实现为环形缓冲区,因此任何域参与者都可以潜在地在其上读取或写入信息。每个端口都有一个唯一的标识符,一个 32 位数字,可用于引用该端口。每个配置了共享内存传输的域参与者都会创建一个端口来接收缓冲区描述符。此端口的标识符在发现期间共享,以便远程对等方知道要与每个域参与者通信时使用哪个端口。

域参与者为其接收端口创建一个侦听器,以便在新的缓冲区描述符被推送到该端口时得到通知。

6.4.1.5 端口健康检查(Port Health Check)

每次域参与者打开一个端口(用于读取或写入)时,都会执行健康检查以评估其正确性。原因是如果涉及的某个进程在使用端口时崩溃,该端口可能会变得无法使用。如果附加的侦听器在给定的超时时间内没有响应,则该端口被视为已损坏,并将其销毁后重新创建。

6.4.2 SharedMemTransportDescriptor

除了在 TransportDescriptorInterface 中定义的数据成员外,共享内存的传输描述符还定义了以下成员:

成员数据类型默认值访问器 / 修改器描述
segment_size_uint32_t512*1024segment_size()共享内存段的大小(以字节为单位)。
port_queue_capacity_uint32_t512port_queue_capacity()监听端口的大小(以消息数为单位)。
healthy_check_timeout_ms_uint32_t1000healthy_check_timeout_ms()端口健康检查的超时时间(以毫秒为单位)。
rtps_dump_file_string""rtps_dump_file()协议转储文件的完整路径。
default_reception_threadsThreadSettingsdefault_reception_threads接收线程的默认 ThreadSettings。
reception_threadsstd::map<uint32_t,ThreadSettings>reception_threads特定端口上接收线程的 ThreadSettings。
dump_thread()ThreadSettingsdump_thread()共享内存转储线程的 ThreadSettings。

如果 rtps_dump_file_ 不为空,则域参与者上的所有共享内存流量(发送和接收的)都会被跟踪到一个文件中。输出文件格式是 tcpdump 十六进制文本,可以使用 Wireshark 等协议分析器应用程序进行处理。具体来说,要使用 Wireshark 打开该文件,请使用“从十六进制转储导入”选项,并使用“原始 IPv4”封装类型。

注意
SharedMemTransportDescriptorkind 值由 LOCATOR_KIND_SHM 给出。

警告
segment_size() 设置为接近或小于数据大小会带来很高的数据丢失风险,因为在单次发送操作期间,写入操作会覆盖缓冲区。

6.4.3 启用共享内存传输

Fast DDS 默认启用共享内存传输。不过,应用程序可以根据需要启用其他共享内存传输。要在域参与者中启用新的共享内存传输,首先创建一个 SharedMemTransportDescriptor 的实例,并将其添加到域参与者的用户传输列表中。

下面的示例展示了在 C++ 代码和 XML 文件中的实现过程。

C++

DomainParticipantQos qos;// 创建新传输的描述符。
std::shared_ptr<SharedMemTransportDescriptor> shm_transport =std::make_shared<SharedMemTransportDescriptor>();// [可选] 线程设置配置
shm_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
shm_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
shm_transport->dump_thread(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});// 将传输层链接到参与者。
qos.transport().user_transports.push_back(shm_transport);

XML

<?xml version="1.0" encoding="UTF-8" ?>
<dds><profiles xmlns="http://www.eprosima.com"><transport_descriptors><!-- 创建新传输的描述符 --><transport_descriptor><transport_id>shm_transport</transport_id><type>SHM</type><default_reception_threads> <!-- 可选 --><scheduling_policy>-1</scheduling_policy><priority>0</priority><affinity>0</affinity><stack_size>-1</stack_size></default_reception_threads><reception_threads> <!-- 可选 --><reception_thread port="12345"><scheduling_policy>-1</scheduling_policy><priority>0</priority><affinity>0</affinity><stack_size>-1</stack_size></reception_thread></reception_threads><dump_thread> <!-- 可选 --><scheduling_policy>-1</scheduling_policy><priority>0</priority><affinity>0</affinity><stack_size>-1</stack_size></dump_thread></transport_descriptor></transport_descriptors><participant profile_name="SHMParticipant"><rtps><!-- 将传输层链接到参与者 --><userTransports><transport_id>shm_transport</transport_id></userTransports></rtps></participant></profiles>
</dds>

注意
如果启用了多种传输,发现流量始终使用 UDP/TCP 传输,即使在同一台机器上运行的两个参与者都启用了共享内存传输也是如此。如果一个或多个参与者仅启用了共享内存,而其他参与者同时使用其他传输,则可能导致发现问题。此外,当同一台机器上的两个参与者启用了共享内存传输时,它们之间的用户数据通信会自动仅通过共享内存传输执行。这些两个参与者之间不会使用其余已启用的传输。

提示
要通过共享内存配置发现流量,必须禁用默认的内置传输。这样,通信就完全使用共享内存执行。下面的代码片段示例展示了在 C++ 代码和 XML 文件中的实现过程。完整示例请参见传输机制示例。

C++

DomainParticipantQos qos;// 创建新传输的描述符。
std::shared_ptr<SharedMemTransportDescriptor> shm_transport =std::make_shared<SharedMemTransportDescriptor>();// 将传输层链接到参与者。
qos.transport().user_transports.push_back(shm_transport);// 显式配置共享内存传输
qos.transport().use_builtin_transports = false;

XML

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com"><transport_descriptors><!-- 创建新传输的描述符 --><transport_descriptor><transport_id>shm_transport_only</transport_id><type>SHM</type></transport_descriptor></transport_descriptors><participant profile_name="DisableBuiltinTransportsParticipant"><rtps><!-- 将传输层链接到参与者 --><userTransports><transport_id>shm_transport_only</transport_id></userTransports><useBuiltinTransports>false</useBuiltinTransports></rtps></participant>
</profiles>

6.4.4 传输机制示例

在 delivery_mechanisms 文件夹中可以找到一个适用于受支持传输机制的“hello world”示例。它展示了通过所需传输机制(可以仅设置为共享内存)进行通信的发布者和订阅者。

本页内容
6.4.1. 概念定义
6.4.1.1. 段
6.4.1.2. 段缓冲区
6.4.1.3. 缓冲区描述符
6.4.1.4. 端口
6.4.2. SharedMemTransportDescriptor
6.4.3. 启用共享内存传输
6.4.4. 传输机制示例

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

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

相关文章

记 2025/9/6

人工智能常见的模型按照处理问题分为6大类&#xff1a;处理权重问题的权重模型、处理状态问题的状态模型、处理序列问题的问题模型、处理表示问题的表示模型、处理相似度的相似模型、处理分类问题的分类模型。权重是计算特定状态下事物的重要性。状态问题是刻画权重动态变化的过…

开启Python之路,第一节学习大纲-从入门到进阶

前端开启Python之路&#xff0c;前端有没有必要卷后端技术&#xff0c;欢迎各位大神批评指正 第一阶段&#xff1a;基础入门 (打好根基) 目标&#xff1a; 理解编程基本概念&#xff0c;掌握 Python 核心语法&#xff0c;能编写简单的脚本程序。 1、环境搭建与开发工具 安装 Py…

webshell及冰蝎双击无法打开?

什么是webshell&#xff1f; web:万维网 shell&#xff1a;是指一种应用程序&#xff0c;为用户和系统之间建立连接&#xff0c;通过这个界面访问操作系统内核的服务 webshell:是以asp、aspx、php、jsp或者cgi等网页文件形式存在的一种命令执行环境&#xff0c;也可以将其称做…

【星闪】Hi2821 | PWM脉宽调制模块 + 呼吸灯例程

1. 简介PWM&#xff08;Pulse Width Modulation&#xff09;&#xff0c;全称脉宽调制&#xff0c;通过对一系列脉冲的宽度进行调制&#xff0c;等效出所需波形。即对模拟信号电平进行数字编码&#xff0c;通过调节频率、占空比的变化来调节信号的变化。一个 PWM 周期内由一段高…

51单片机---硬件学习(电子琴、主从应答模式、modbus模型、DS18B20传感器显示温度)

一、串行通信与并行通信1、串行通信定义&#xff1a;数据一位一位地按顺序通过单条传输线进行传输的通信方式。优点&#xff1a;传输线少&#xff0c;成本低&#xff0c;适合长距离传输缺点&#xff1a;传输速度相对较慢2、并行通信定义&#xff1a;数据的各位同时通过多条并行…

SpringBoot后端开发常用工具详细介绍——SpringSecurity认证用户保证安全

简单的开始 创建SpringBoot项目 首先创建一个简单的springboot项目&#xff0c;假设端口为8888&#xff0c;添加controller控制层&#xff0c;并在其中添加TestController控制类&#xff0c;那么启动springboot项目之后&#xff0c;访localhost:8888/api/message页面会显示my…

别再手工缝合API了!开源LLMOps神器LMForge,让你像搭积木一样玩转AI智能体!

你是否受够了这些&#xff1f; 刚调通OpenAI的API&#xff0c;老板说“咱们试试国产模型降本增效”&#xff0c;你看着满屏的if-else只想说“我晕”。想给AI加上“查天气”、“执行代码”的能力&#xff0c;却发现Function Calling的代码复杂得让人头皮发麻。本地的Agentdemo惊…

window使用ffmep工具,加自定义脚本执行视频转码成h264(运营人员使用)

技术文章大纲&#xff1a;ffmep配合脚本使用1. 需要提供脚本给视频转码的给运营,给运营上传视频使用安装ffmep windows版本(目前我使用的就是windows)将脚本里面的执行路径修改成自己的电脑安装ffmep/bin/ffmep.exe路径处理好之后就点击执行2.环境准备ffmep windows版解压到一个…

Leetcode 240. 搜索二维矩阵 II 矩阵 / 二分

原题链接&#xff1a; Leetcode 240. 搜索二维矩阵 II 解法一&#xff1a;排除法 参考 【图解】排除法&#xff0c;一图秒懂&#xff01;&#xff08;Python/Java/C/C/Go/JS/Rust&#xff09; 从右上角&#xff1a; class Solution { public:bool searchMatrix(vector<vec…

OCR 证件识别:驱动澳门酒店自助入住智能化

澳门酒店作为国际旅游窗口&#xff0c;每日接待持多元证件的旅客&#xff0c;OCR 证件识别技术的应用&#xff0c;让自助入住终端实现 “一证通办”&#xff0c;大幅提升服务效率。​旅客在自助终端办理入住时&#xff0c;只需将护照、港澳通行证、回乡证、电子身份证等证件贴近…

深入解析汇编语言的奥秘

汇编语言简介汇编语言&#xff08;Assembly Language&#xff09;是一种低级编程语言&#xff0c;直接对应计算机的机器指令集。它通过助记符&#xff08;如 MOV、ADD&#xff09;代替二进制操作码&#xff0c;更接近硬件架构&#xff0c;常用于性能优化、嵌入式开发或逆向工程…

Nextcloud 实战:打造属于你的私有云与在线协作平台

随着数据安全与隐私保护意识的提升&#xff0c;越来越多的个人和组织选择自建云平台来替代公有云。Nextcloud 作为一款开源的文件同步与协作套件&#xff0c;不仅能实现类似网盘的文件存储与分享&#xff0c;还提供日历、联系人、即时通讯、在线文档编辑等协作功能&#xff0c;…

实践指南:利用衡石AI Data Agent实现自然语言驱动的指标开发与归因

在数字化转型的深水区&#xff0c;企业数据团队常面临两难困境&#xff1a;业务部门需要敏捷响应的指标分析&#xff0c;但传统BI工具依赖技术团队编写SQL&#xff0c;导致需求交付周期长达数周&#xff1b;而直接暴露底层数据又存在安全与合规风险。衡石科技推出的AI Data Age…

知微集:Python中的线程(三)

欢迎来到"一起学点什么吧"的合集「NLP知微集」。在这里&#xff0c;我们不愿宏大叙事&#xff0c;只聚焦于自然语言处理领域中那些细微却关键的“齿轮”与“螺丝钉”。我相信&#xff0c;真正深刻的理解&#xff0c;源于对细节的洞察。本期&#xff0c;我将为您拆解的…

动态规划入门:从记忆化搜索到动态规划

在开始对动态规划的讲解之前&#xff0c;我们需要先对记忆化搜索进行回顾&#xff1a; 什么是记忆化搜索&#xff1f; 在搜索过程中&#xff0c;当搜索树中存在大量重复的节点时&#xff0c;我们可以通过引入一个"备忘录"&#xff08;通常是一个数组或哈希表&#…

Boost搜索引擎 网络库与前端(4)

文章目录前言一、引入网络库模块引入cpp-httplibcpp-httplib测试正式编写http_server二、前端模块三、项目的可能拓展总结前言 终于到了最后一篇喽&#xff0c;嘻嘻&#xff01; 一、引入网络库模块 引入cpp-httplib 下载地址如下&#xff0c;我个人不喜欢新版本   cpp-http…

Flink反压问题

背景在使用flink的过程中&#xff0c;多次遇到过反压&#xff08;backpressure&#xff09;的问题&#xff0c;这通常是因为数据处理的速率超过了数据源或下游系统的处理能力导致。反压的底层剖析网络流控一个重要的概念是网络流控&#xff0c;如上图&#xff0c;不同的Consume…

Day5-中间件与请求处理

昨天搞定了异步优化&#xff0c;今天来解决一些实际问题。Day4的API虽然性能不错&#xff0c;但还缺少一些企业级应用必备的功能。 现在的问题 前端无法访问API&#xff08;跨域问题&#xff09;没有请求日志&#xff0c;出问题难以排查错误信息格式不统一缺少统一的请求处理机…

【LeetCode热题100道笔记】反转链表

题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a;输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a;输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&#xff1a;…

Oracle:select top 5

在Oracle数据库中实现SELECT TOP 5功能需采用特定语法&#xff0c;因其原生不支持TOP关键字。以下是两种主流实现方式&#xff1a;‌ROWNUM结合子查询‌先通过子查询排序数据&#xff0c;再在外层用ROWNUM限制行数&#xff1a;SELECT * FROM ( SELECT * FROM 表名 ORDER BY 排序…