【QNX】Qnx IPC通信 Message-passing

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 );// 这里只回复了客户端状态。第三的参数和第四个参数,是回复客户端的数据,及SizeMsgReply(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() {// 发送的Msgmy_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.mzph.cn/pingmian/16124.shtml

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

相关文章

【数据结构与算法 经典例题】判断链表是否带环

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 期待您的关注 目录

dubbo复习:(9)配置中心的大坑,并不能像spring cloud那样直接从配置中心读取自定义的配置

配置中心只是为 Dubbo 配置提供管理使用的&#xff08;比如配置服务超时时间等)。不要尝试通过Value类似的方式从dubbo 配置中心(比如nacos、zookeeper、Apollo)来获取数据 https://github.com/apache/dubbo/issues/11200可以在application.yml中主要写注册中心的配置&#xf…

【深度学习基础】NumPy数组库的使用

目录 写在开头 一、数组的类型与维度 数组的类型 数组的维度 二、数组的创建 递增数组 同值数组 随机数数组 三、数组的索引 访问/修改单个元素 花式索引 数组的切片 四、数组的变形 数组的转置 数组的翻转 数组的形状改变 数组的拼接 五、数组的运算 数…

Linux系统启动原理

Linux系统启动原理及故障排除 Centos6系统启动过程 修改系统启动级别 vim /etc/inittabCentos7启动流程 加载BIOS信息&#xff0c;进行硬件检测 根据BIOS设定读取设备中的MBR&#xff0c;加载Boot loader 加载内核&#xff0c;内核初始化以后以模块的形式动态加载硬件 并且加…

FFmpeg的流程

文章目录 前序代码结构FFmpeg.cffmpeg_opt.c 小结 前序 之前看过FFmpeg的各种命令&#xff0c;然后不是很理解。相信很多人都不是很理解&#xff0c;毕竟&#xff0c;单纯的去记住那些命令行本身就需要很大的内存&#xff0c;我们的大脑内存又有限&#xff0c;所以&#xff0c…

java “错误:编码GBK 的不可映射字符”

环境&#xff1a;JDK-17 本机编码&#xff1a;utf-8 代码编码&#xff1a;GBK 错误&#xff1a;java “错误&#xff1a;编码GBK 的不可映射字符” 解决1&#xff1a;记事本打开java源文件&#xff0c;另存为选择ANSI编码 解决2&#xff1a;复制代码再将编码格式改为utf-8,…

java欢迪迈手机商城设计与实现源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的欢迪迈手机商城设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 欢迪迈手机商城…

spring状态机实战

一、什么是状态机 状态机是有限状态自动机的简称&#xff0c;是现实事物运行规则抽象而成的一个数学模型&#xff0c;是一种概念性机器&#xff0c;它能采取某种操作来响应一个外部事件。这种操作不仅能取决于接收到的事件&#xff0c;还能取决于各个事件的相对发生顺序。状态…

不同网段的通信过程

这里的AA和HH指的是mac地址&#xff0c;上面画的是路由器 底下的这个pc1&#xff0c;或者其他的连接在这里的pc&#xff0c;他们的默认网关就是路由器的这个192.168.1.1/24这个接口 来看看通信的过程 1、先判断&#xff08;和之前一样&#xff09; 2、去查默认网关&#xf…

基于SpringBoot和Hutool工具包实现的验证码案例

目录 验证码案例 1. 需求 2. 准备工作 3. 约定前后端交互接口 需求分析 接口定义 4. Hutool 工具介绍 5. 实现验证码 后端代码 前端代码 6. 运行测试 验证码案例 随着安全性的要求越来越高&#xff0c;目前项目中很多都会使用验证码&#xff0c;只要涉及到登录&…

Liunx系统中修改文件的创建时间以及访问时间

在Linux系统中&#xff0c;可以使用touch命令来修改文件的时间戳。以下是一些常用的touch命令选项&#xff1a; &#xff08;其实在MacOS中也适用&#xff09; 修改访问时间&#xff08;Access Time&#xff09;和修改时间&#xff08;Modification Time&#xff09;&#xf…

Celery的Web监控工具Flower

1 简介Flower Flower官网 Flower是一个WEB端的监控工具&#xff0c;可以监控Celery的消费者。但是WEB端的监控对于监控系统来说&#xff0c;有个屁用&#xff0c;有用的是监控告警。还好Flower不是全部是垃圾&#xff0c;它提供的Prometheus的监控端点。然而。。。。。如何保证…

CorelCAD v2022.5 解锁版 安装教程(2D制图 3D设计和打印的简化软件)

前言 CorelCAD&#xff0c;加拿大Corel公司开发的一款适用于2D制图、3D设计和打印的简化版CAD软件。它是款专业的2D制图和3D设计软件&#xff0c;拥有行业标准文件兼容性&#xff0c;支持 .DWG、.STL、.PDF、 .CDR*等文件格式&#xff0c;轻松实现协作和项目共享&#xff0c;利…

学 Go 具体能干什么?

学习 Go (Golang) 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;Go 语言以其高性能、并发处理和简洁的语法而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 后端开发 Go 在后端开发中非常流行&#xff0c;特别适合构建高性能的 Web 服务和 API。 Web 框…

【机器学习】基于核的机器学习算法(Kernel-based Algorithms):原理,应用与优化

&#x1f440;传送门&#x1f440; 文章引言&#x1f50d;&#x1f340;核函数的概念&#x1f680;基于核的算法原理&#x1f496;基于核的算法应用&#x1f41f;支持向量机&#xff08;SVM&#xff09;&#x1f4d5;核主成分分析&#xff08;KPCA&#xff09; &#x1f340;未…

大数据信用报告查询有哪些作用?哪个平台更好?

大数据信用是基于大数据技术&#xff0c;通过大数据系统生成的大数据信用报告&#xff0c;报告收集了查询人在非银环境下的申贷数据以及履约行为和信用风险的综合性报告。很多人都会问&#xff0c;大数据信用报告查询有哪些作用?哪个查询平台更好的疑问&#xff0c;下文就详细…

C++STL---string知识汇总

前言 我们现在开始CSTL的学习&#xff0c;从这时开始我们就要锻炼自己查看英文文档的能力&#xff0c;每种数据结构都有上百个接口函数&#xff0c;我们把他们全部记下来是不可能的&#xff0c;所以我们只记最常见的20几个接口&#xff0c;其他的大概熟悉有什么功能&#xff0…

深入JVM元空间以及弹性伸缩机制

个人博客 深入JVM元空间以及弹性伸缩机制 | iwts’s blog JVM内存模型中元空间所在位置 即在JVM运行时的内存模型。总体上有这样的图&#xff1a; 元空间 上面的图其实有点不太准。方法区本质上只是JVM的一个标准&#xff0c;不同JVM在不同版本下都可能有不同的实现&#x…

Matlab中函数或变量 ‘eeglab‘ 无法识别

EEGLAB 没有安装或添加到 MATLAB 路径中&#xff1a; 确保已经安装了 EEGLAB&#xff0c;并且将其添加到 MATLAB 的路径中。您可以通过在 MATLAB 命令窗口中运行 which eeglab 来检查是否能够找到 EEGLAB。 EEGLAB 函数路径设置错误&#xff1a; 如果已经安装了 EEGLAB&#x…