【QNX】Qnx IPC通信 Message-passing

news2024/11/16 2:07:30

Qnx IPC通信 Message-passing

Message-passing介绍

QNX提供了多种IPC(Interprocess Communication )通信方式,包括Message-passing、Plus(脉冲)、Event、Signal、共享内存、Pipe,当然还有socket。
Message-passing是Qnx IPC的主要形式。

Synchronous messaging is the main form of IPC in the QNX Neutrino RTOS.

Message-passing提供了主从直接同步的双向消息传输,类似于Android 同步Binder。
客户端向服务端请求(Request),服务端向客户端(Reply)。

官网链接:
https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.sys_arch/topic/ipc_Sync_messaging.html

通信状态迁移图

在这里插入图片描述
Qnx官网给出的客户端状态迁移图。

  • 客户端调用MsgSend(Qnx提供的函数),客户执行函数的所在线程,进入SednBlocked的阻塞状态(等待服务端回复)
  • 服务端执行MsgRecevice,接收客户端的请求后。Qnx kernel会将Client端的Thread调度为Repley blocked状态。
  • 服务端处理完客户端的请求后,调用MsgReply或者MsgError,返回结果给Client端。Client从blocked阻塞状态,变为Ready非阻塞状态。

在这里插入图片描述
Qnx官网给出的服务端状态迁移图

  • 服务端调用MsgReceive接收客户端请求(阻塞)
  • 客户端端调用MessageSend后,服务端收到调用,从阻塞状态中退出。处理请求后,通过MsgReply()/MsgError回复客户端。
  • 服务端重新调用MsgReceive,监听客户端请求。

Channels and connections

Qnx中消息传递(Message-passing)是基于通道/连接 这种方式,进行传输的。

  • 一个thread(看做任务的基本调度单位)想要接收消息,必须创建一个通道(Channels)
  • 一个thread 想要发送消息,必须连接(connections)到这个通道。

在这里插入图片描述
Qnx官网关于Channels and connections的说明图片。

关于性能

根据QNX官网的介绍,Message-passing时,Qnx Kernel基于地址空间,直接把消息从当前线程的地址,复制到接收线程的地址,没有额外的中间拷贝。所以接近于硬件上内存的带宽(很快)

Since our messaging services copy a message directly from the address space of one thread to another without intermediate buffering, the message-delivery performance approaches the memory bandwidth of the underlying hardware.

Message-passing例子

Qnx官网给出了例子,这里借用分析一下例子。

  • 服务端
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dispatch.h>

#define ATTACH_POINT "myname"
// 定义消息数据的类型
typedef struct _my_data
{
    uint16_t type;
    int value;
} my_data_t;

// 在特殊情况下,比如客户端断开,会收到来自Qnx Kernel的消息。
// 这个时候通过 qnx提供的_pulse 来接收
typedef union recv_buf
{
    uint16_t type;
    struct _pulse pulse;
    my_data_t data;
} my_recv_buf_t;

int server() {
   name_attach_t *attach;
   my_recv_buf_t msg;
   int rcvid;

   // 创建一个通道
   if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL) {
       return EXIT_FAILURE;
   }
    
   // 开启循环,监听客户端请求
   while (1) {
       rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);

       if (rcvid == -1) {
           // Error了
           break;
       }

       // 表示接口到Plus消息(来自Qnx系统发送的消息)
       if (rcvid == 0) {
           switch (msg.pulse.code) {
           case _PULSE_CODE_DISCONNECT:
               /*
                * A client disconnected all its connections (called
                * name_close() for each name_open() of our name) or
                * terminated
                */
               // 客户端断开
               ConnectDetach(msg.pulse.scoid);
               break;
           case _PULSE_CODE_UNBLOCK:
               /*
                * REPLY blocked client wants to unblock (was hit by
                * a signal or timed out).  It's up to you if you
                * reply now or later.
                */
                // 客户端长期阻塞在REPLY blocked状态。请求解除阻塞
               break;
           default:
               /*
                * A pulse sent by one of your processes or a
                * _PULSE_CODE_COIDDEATH or _PULSE_CODE_THREADDEATH
                * from the kernel?
                */
                // 这段看qnx官方注释即可
               break;
           }
           continue;
       }

       /* A system message was received, reject it. */
       if (msg.type <= _IO_MAX ) {
           MsgError( rcvid, ENOSYS );
           continue;
       }

       /* A message (presumable ours) received, handle */
       printf("Server receive %d \n", msg.data.value);
       // 回复客户端消息
       // 
       // int MsgReply( int rcvid,
       //       long status,
       //       const void* msg,
       //       size_t bytes );
       // 这里只回复了客户端状态。第三的参数和第四个参数,是回复客户端的数据,及Size
       MsgReply(rcvid, EOK, 0, 0);

   }

   /* Remove the name from the space */
   name_detach(attach, 0);

   return EXIT_SUCCESS;
}

int main(int argc, char **argv) {
    int ret = server();
    return ret;
}
  • 客户端
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dispatch.h>

#define ATTACH_POINT "myname"

// 定义消息数据的类型
typedef struct _my_data
{
    uint16_t type;
    int value;
} my_data_t;


int client() {
    // 发送的Msg
    my_data_t msg;
    int server_coid;
    // 连接通道
    if ((server_coid = name_open(ATTACH_POINT, 0)) == -1) {
        return EXIT_FAILURE;
    }

    /* We would have pre-defined data to stuff here */
    msg.type = (_IO_MAX+5);

    // 给Server发送消息
    for (msg.value=0; msg.value < 5; msg.value++) {
        printf("Client sending %d \n", msg.value);
        // 这里只接受了服务端回复的状态(MsgSend的返回值)
        // long MsgSend( int coid,
        //       const void* smsg,
        //       size_t sbytes,
        //       void* rmsg,
        //       size_t rbytes );
        // 第三个参数和第四个参数,表示从服务端收到的数据。
        if (MsgSend(server_coid, &msg, sizeof(msg), NULL, 0) == -1) {
            break;
        }
    }

    /* Close the connection */
    name_close(server_coid);
    return EXIT_SUCCESS;
}

int main(int argc, char **argv) {
    int ret = client();
    return ret;
}

如果有Qnx环境的上,编译上述程序后。在qnx环境下先运行Server,然后运行Client即可。

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

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

相关文章

远大阀门集团携创新产品亮相南京,展现石化行业新风采

2024年5月22日&#xff0c;备受瞩目的第八届中国石油和化工行业采购大会在江苏省南京市盛大开幕。作为石化行业物资采购领域极具影响力的年度盛会&#xff0c;本次大会吸引了众多国内外能源化工企业、化工新材料企业、工程公司以及相关领域的供应商参加。远大阀门集团作为特邀优…

【网络安全】Fortinet FortiSIEM 中存在严重未经身份验证的 RCE 漏洞:已发布 PoC

文章目录 什么是Fortinet Forti SIEMFortinet Advisor — FortiSIEM 内置生成式 AI 优势功能下一代 SOC 自动化通过链路分析实现可视化威胁猎捕 RCE 漏洞和 PoC如何降低影响推荐阅读 针对 Fortinet FortiSIEM 中一个严重的未经身份验证的远程代码执行漏洞&#xff08;CVE-2023-…

NVIDIA Orin/Jetson 平台+数字同轴GMSL 车载AI视觉方案,应用于车载,机器人等领域

专注于成像和视觉技术于近期正式发布了可适配NVIDIA DRIVE AGX Orin平台的一系列摄像头产品&#xff0c;该产品是自主开发的数字同轴GMSL2摄像头模组&#xff0c;可满足智能汽车的高质量成像需求。 目前&#xff0c;推出可适配于NVIDIA DRIVE AGX Orin平台的摄像头产品一共有11…

ubuntu安装Stable Video Diffusion(SVD)让图片动起来

目录 写在前面 一、克隆或下载项目 二、下载预训练模型 三、创建环境 四、安装依赖 五、启动项目 六、解决报错 1.预训练模型下不来 2.TiffWriter.write() got an unexpected keyword argument fps 3.安装ffmpeg 4.No module named scripts 七、测试 写在前面 Stab…

华为机考入门python3--(30)牛客30-字符串合并处理

分类&#xff1a;字符串、进制转换 知识点&#xff1a; 获取偶数下标的字符 even_chars my_str[::2] 获取奇数下标的字符 odd_chars my_str[1::2]) 翻转字符串 reversed_str my_str[::-1] 二进制转十进制 num int(reversed_binary, 2) 十进制转十六进制 …

JWT的生成

引依赖 生成JWT JWT校验 注意

Kubernetes(k8s) v1.30.1 本地集群部署 安装metallb 支持LoadBalancer 生产环境 推荐 BGP模式部署

1 metallb 安装参考:Kubernetes(k8s) v1.30.1 本地集群部署 默认不支持LoadBalancer metallb来解决-CSDN博客 2 删除 Layer 2 模式 配置 kubectl delete -f IPAddressPool.yaml kubectl delete -f L2Advertisement.yaml kubectl delete -f discuz-srv.yaml 3 配置 k8s Metal…

IDEA 2024.1安装与破解

一、下载 官网地址&#xff1a;https://www.jetbrains.com/idea/download/other.html 二、安装 傻瓜式安装即可 三、破解 3.1 破解程序 网站&#xff1a;https://3.jetbra.in/ 3.2 获取激活码 点击*号部分即可复制成功

【机器学习】——线性模型

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

typescript 配置精讲 | moduleResolution

大家好&#xff0c;我是17。 moduleResolution 是 typescript 模块配置中最重要的一个配置&#xff0c;所以 17 单拿出来讲一下。如果你去看文档还是挺复杂的&#xff0c;但如果不去深究细节&#xff0c;只想知道如何配置还是很简单的。3 分钟就能学会。 moduleResolution 的…

neo4j开放远程连接

注&#xff1a;本博客所用neo4j版本为社区5.12版 第一步&#xff1a;修改neo4j配置文件 首先找到neo4j的安装位置&#xff0c;点击进入conf文件夹&#xff0c;随后点击neo4j.conf文件&#xff0c;在“Network connector configuration”下面的单元中找到server.default_liste…

奥枫软件Java要个16K遇到地狱级难度,醉了。。。

我只能说地狱难度&#xff0c;没绝对把握就别去了。我凭借前辈的经验&#xff0c;和当时天时地利人和&#xff0c;六道题答得很不错&#xff0c;但还是没通过。我有备而来都没过&#xff0c;现场写那些应该都是白忙活了。 一面 1&#xff0c;分割一个整数。如123&#xff0c;结…

贪心-AcWing 125. 耍杂技的牛-XMUOJ蒙德冒险者的游戏

题目 思路 每头牛的危险值 他前面牛的w(重量值)之和 - 自身的s(强壮值) 要使每头牛的危险值最小&#xff0c;根据贪心思想&#xff1a; 自身w值越大应该放到底部&#xff08;即减小上述式中的被减数&#xff09; 自身s值越大应该放到底部&#xff08;即增大上述式中的减数&…

KingbaseES数据库union的用法

数据库版本&#xff1a;KingbaseES V008R006C008B0014 文章目录如下 1. union的概念 2. union的语法 3. union的用法 3.1. 去重&#xff08;union&#xff09; 3.2. 不去重&#xff08;union all&#xff09; 3.3. 聚合运算 3.4. 异常案例 1. union的概念 UNION 是结构…

ClickHouse架构概览 —— Clickhouse 架构篇(一)

文章目录 前言Clickhouse 架构简介Clickhouse 的核心抽象列和字段数据类型块表 Clickhouse 的运作过程数据插入过程数据查询过程数据更新和删除过程 前言 本文介绍了ClickHouse的整体架构&#xff0c;并对ClickHouse中的一些重要的抽象对象进行了分析。然后此基础上&#xff0…

揭秘OS模块:文件与文件夹的遍历艺术

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、os.listdir()&#xff1a;当前目录的扫描者 三、os.walk()&#xff1a;文件系…

深度学习——自己的训练集——训练模型(CNN)

训练模型 1.导入必要的库2.加载类别名称3.创建标签映射字典4.加载图像数据和对应的标签5.构建和编译CNN模型6.训练模型7.保存训练好的模型 1.导入必要的库 导入处理数据和训练模型时需要的库 os: 这个模块提供了与操作系统交互的功能&#xff0c;比如文件和目录操作。 cv2: 这…

如何选择优质的气膜体育馆工程服务商—轻空间

随着现代生活的便利化和时代感的增强&#xff0c;气膜体育馆成为越来越多人的选择。这种美观实用的建筑在学校、社区和体育中心等地广泛应用。许多投资者和客户都有意建造气膜体育馆&#xff0c;但在选择工程服务商时&#xff0c;往往面临困惑。以下几点将帮助您做出明智的选择…

grafana大盘展示node_expod节点

node_expod添加lables标签 Prometheus查询 语句查询 node_exporter_build_infografna添加变量查询 正常有值 切换其他的是有值的 我的报错原因 因为有多个数据源,我选择错了,因为修改的lable标签是其他数据源,所以获取不到 查询语句 我的变量是 $app node_filesyste…

【优选算法】位运算 {位运算符及其优先级;位运算的应用:判断位,打开位,关闭位,转置位,位图,get lowbit,close lowbit;相关编程题解析}

一、位运算符及其优先级 我们知道&#xff0c;计算机中的数在内存中都是以二进制形式进行存储的 &#xff0c;而位运算就是直接对整数在内存中的二进制位进行操作&#xff0c;因此其执行效率非常高&#xff0c;在程序中尽量使用位运算进行操作&#xff0c;这会大大提高程序的性…