转载:https://blog.csdn.net/xjhhjx/article/details/77139457

一、QNX消息概述
QNX消息可以分为同步消息和异步消息。异步(脉冲)消息主要体现的是一种通知机制,同步消息主要是说消息在传递过程需要双方相互配合的过程。
二、QNX消息传递几个基本概念
1、频道与链接
消息传递是基于服务器与客户端的模式来进行的,QNX6抽象出了”频道“(Channel)这个概念。一个频道,就是一个服务的入口;至于这个频道到底具体有多少线程为其服务,那都是服务器端自己的事情。一个服务器如果有多个服务,它也可以开多个频道。而客户端,在向“频道”发送消息前,需要先建立连接(Connection),然后将消息在连接上发出去。这样同一个客户端,如果需要,可以与同一个频道建立多个连接。
2、名字空间(name_space)
在客户端与服务器通信中,为了让客户端方便的知道服务器的nd/pid/chid, 服务器进程可以注册一个路径名,与服务频道的nd, pid, chid关联起来。客户端就只要请求连接版务器路径名就可以了。

三、QNX同步信号下客户端服务器通信

1、客户端模型
1)调用name_open(PATH)连接到服务器频道获得一个连接ID
3)调用API发送消息等待服务器应答
4)收到应答完毕调用name_close()关闭连接

2、服务器模型
1)调用name_attach注册一个名字空间并且创建一个频道
2)接收并处理消息
3)应答消息处理结果
4)name_detach从名字空间删除该名称

3、客户端服务器消息传递过程
1)服务器注册一个名字空间等待客户端连接
2)客户端连接到名字空间
3)客户端调用MsgSend接口给服务器发送消息,客户端处于发送阻塞
4)服务器调用MsgReceive接口接收数据,客户端处于应答阻塞
5)服务器处理完毕消息,调用MsgReply函数发送应答消息
6)客户端从MsgSend函数返回,解除阻塞

4、利用多路消息传递提高效率
用iov_t来“汇集”数据。也就是说,可以一次传送几块据。Header同databuf是两块不相邻的内存,但传递到服务器端的ReceiveBuffer里,就是连续的了。
SETIOV(&iov[0], &header, sizeof(header));
SETIOV(&iov[1], databuf, datalen);
MsgSendvs(ConnectionId, iov, 2, Replybf, ReplyLen);

5、消息传递的方向与MsgDeliverEvent()
客户端给服务器发送消息,服务器不能立刻应答而客户端不想等待。遇到这种情况,正确的做法是,告诉客户端,请求一段时间后会得到处理,客户端得以继续运行,一旦服务器完成任务,服务器需要一些方式告诉客户端请求完成。

客户端: 准备一个“通知事件”(Notification Event),并把这个事件用MsgSend()发给服务器端,意思是:“如果xxx情况发生的话,请用这个事件通知我”。
  服务器: 收到这个消息后,记录下当时的rcvid,和传过来的事件,然后应答“好的,知道了”。 
  客户端: 因为有了服务器的应答,客户端不再阻塞,可以去做别的事 
  ...... 
  服务器: 在某个时刻,客户端所要求的“xxx情况”满足了,服务器调用 MsgDeliverEvent(rcvid, event);以通知客户端 
  客户端: 收到通知,再用MsgSend()发关“xxx 情况的数据在哪里?” 
  服务器: 用MsgReply()把数据返回给客户端

int MsgDeliverEvent (int rcvid,const struct sigevent *event);
event服务器不需要作修改 rcvid是服务器从客户端接收的。当服务器给客户端应答后,这个id将失去意义。另外MsgDeliverEvent是非阻塞函数。

6、常用API
ChannelCreate(), ChannelDestroy()
    ConnectAttach(), ConnectDetach()
    MsgDeliverEvent()
    MsgError()
    MsgRead(), MsgReadv()
    MsgReceive(), MsgReceivePulse(), MsgReceivev()
    MsgReply(), MsgReplyv()
    MsgSend(), MsgSendnc(), MsgSendsv(), MsgSendsvnc(), MsgSendv(), 
MsgSendvnc(), MsgSendvs(), MsgSendvsnc()
  MsgWrite(), MsgWritev()

name_attach(), name_close(), name_detach(), and name_open()

7、总结
1)客户端在给服务发送消息的时候指定服务器应答缓冲区
2)服务器给客户端应答消息(MsgReply)的时候传递参数作为MsgSend返回值
3)服务器在MsgReceive的时候可以传递参数用于获取客户端发送的消息的一些信息
4)客户端在打开服务名字空间的时候系统会发送一个_IO_CONNECT 消息给服务器
5)客户端断开连接或者关闭名字空间的时候服务器会收到_PULSE_CODE_DISCONNECT脉冲
6)客户端视图从REPLY BLOCK解除阻塞的时候服务器会收到_PULSE_CODE_UNBLOCK脉冲
7)创建名字空间的时候自动设置了_NTO_CHF_DISCONNECT_NTO_CHF_COID_DISCONNECT 、_NTO_CHF_UNBLOCK 标准,故服务器可以收到对应系统脉冲

四、通知信号-脉冲
1、基本概念
脉冲其实更像一个短消息,也是在“连接”上发送的。脉冲最大的特点是它是异步的。发送方不必要等接收方应答,直接可以继续执行。但是,这种异步性也给脉冲带来了限制。脉冲能携带的数据量有限,只有一个8位的"code"域用来区分不同的脉冲,和一个32位“value"域来携带数据。脉冲最主要的用途就是用来进行“通知”(Notification)。不仅是用户程序,内核也会生成发送特殊的“系统脉冲”到用户程序,以通知某一特殊情况的发生。

2、接收脉冲
知道频道上不会有别的消息,只有脉冲的话,可以用MsgReceivePulse()来只接收脉冲;如果频道既可以接收消息,也可以接收脉冲时,就直接用MsgReceive(),只要确保接收缓冲(ReveiveBuf)至少可以容下一个脉冲(sizeof struct _pulse)就可以了。如果MsgReceive()返回的rcvid是0,就代表接收到了一个脉冲,反之,则收到了一个消息。

3、脉冲信号特点
1)有效传递40位数据(8位脉冲码,32位数据)
2)对发送者而言是非阻塞的
3)可以像其他消息一样被接受
4)脉冲会排队,只要接受者不是阻塞等待脉冲。
5)若没有脉冲,则接收者会阻塞等待脉冲

4、相关数据结构与API
struct _pulse {
      uint16_t type;
      uint16_t subtype;
      int8_t code;
      uint8_t zero [3];
      union sigval value;
      int32_t scoid;
  };
value是一个联合体
      union sigval {
      int sival_int;
      void *sival_ptr;
     };

int MsgReceivePulse (int chid,
        void *rmsg,
        int rbytes,
        struct _msg_info *info);

五、异步消息

1、异步信号常用API
asyncmsg_channel_create()
asyncmsg_channel_destroy()
asyncmsg_connect_attach()
asyncmsg_connect_detach()
asyncmsg_flush()
asyncmsg_put(),
asyncmsg_get()
asyncmsg_free()
asyncmsg_malloc()

2、API说明
int asyncmsg_channel_create (
unsigned flags,
mode_t mode,
size_t buffer_size,
unsigned max_num_buffer,
const struct sigevent *ev,
int (*recvbuf_callback) (
size_t bufsize,
unsigned num_bufs,
void *bufs[],
int flags,
void *handle ),
void *recvbuf_callback_handle );

Flags:描述频道属性,默认设置_NTO_CHF_ASYNC,如果设置_NTO_CHF_ASYNC_NONBLOCK 
那么程序在调用asyncmsg_get()的时候如果没有消息到来将不会阻塞。

Mode:设置频道属性

Buff_size:设置存放消息的缓冲的大小

Max_num_buffer:设置存放消息的缓冲区最大个数

Ev:NULL或者一个指向sigevent结构体的指针,用于指定一个事件,当有消息可以被接收的时候这个事件自动发送

Recvbuf_callback:NULL或者一个函数指针,用于分配空间存放接收的消息为NULL时候用Malloc

recvbuf_callback_handle:传递给Recvbuf_callback函数。

说明:
当Recvbuf_callback不为NULL的时候:
每当调用一次asyncmsg_get()的时候触发一次回调函数(flags设置为ASYNCMSG_RECVBUF_ALLOC,bufs指向消息...)当希望接收其他消息的时候返回1,返回0停止。
调用 asyncmsg_channel_destroy()的时候,回调函数被触发多次用于释放空间,flags设置为ASYNCMSG_RECVBUF_FREE。

int asyncmsg_channel_destroy( int chid );

chid :频道ID
说明:
当Recvbuf_callback不为NULL的时候,每次调用会触发释放空间,默认调用free。

返回值:
成功:EOK
失败:-1 ->errno

int asyncmsg_connect_attach (
uint32_t nd,
pid_t pid,
int chid,
unsigned index,
unsigned flags, 
const struct _asyncmsg_connection_attr * attr);

参数说明:
Nd/pid/chid:哪台电脑/进程ID/频道ID

index:最低可接受的连接ID(起始值)

Flags:
_NTO_COF_NOSHARE:应用程序使用自己的BUFFER,否则使用asyncmsg_malloc(),填充数据调用asyncmsg_put()的时候发送。

_NTO_COF_NONBLOCK:不用阻塞等待,当发送头部忙的时候
Attr:
指定连接属性
返回值:
成功:连接ID
失败:-1

int asyncmsg_connect_detach( int coid );

参数:
coid :连接ID
备注:
从指定连接断开,所有在发送放一侧的消息被丢弃,如果为了在这之前所有的消息被发送完毕,在这之前调用asyncmsg_flush()接口。

返回值:
成功:EOK
失败:-1

int asyncmsg_flush( int coid,
int mode );

参数说明:
Coid:连接ID

Mode:
0,如果不想该函数阻塞则设置ASYNCMSG_FLUSH_NONBLOCK

返回值:
成功:EOK
失败:-1

int asyncmsg_connect_attr (
int coid,
struct _asyncmsg_connection_attr *old_attr, 
const struct _asyncmsg_connection_attr *new_attr);

参数说明:
coid:连接ID
Old_attr:当前属性
new_attr:新的属性

返回值:
成功:EOK
失败:-1

int asyncmsg_put( int coid,
const void *buff,
size_t size, 
unsigned handle),
int (*call_back) (
int err,
void* buf,
unsigned handle ));

int asyncmsg_putv( int coid,
const iov_t* iov,
int parts, 
unsigned handle,
int (*call_back) (
int err,
void* buf,
unsigned handle ));
参数说明:
Coid:连接ID
Buff:消息缓冲
Size:消息大小
Iov:存放IOV消息的数组
Parts:IOV数组大小
Handle:用户自定义数据传递给回调函数,用于区分包类型
call_back:NULL或则一个函数指针,消息传递后调用,如果为NULL则
_asyncmsg_connection_attr 传递给asyncmsg_connect_attach被调用。

struct _asyncmsg_get_header *asyncmsg_get( int chid );

参数说明:
Chid:频道ID
说明:函数最多接收5个异步消息,为了接收更多的消息,应该循环调用这个接口,知道返回NULL并且errno为EAGAIN的时候意味着读取完毕。

返回类型:
struct _asyncmsg_get_header {
struct _msg_info info;
int err;
iov_t *iov;
int parts;
struct _asyncmsg_get_header *next;
unsigned reserve[2];
};
说明:

Info:异步信号信息结构
err:错误状态
Ivo:指向消息体
Parts:ivo数组大小
Next:指向下一个信息结构体

返回值:
成功:信息链表
失败:NULL

void asyncmsg_free( void *buf);

参数说明:
buf:释放内存的指针
说明:
 asyncmsg_get()调用促使释放内存

void *asyncmsg_malloc( size_t size );

说明:
函数为发送消息分配空间。

QNX操作系统信息传递-qnx任务之间的消息传递信息传递相关推荐

  1. QNX操作系统和QNX Hypervisor简介

    概述 QNX操作系统和QNX Hypervisor是由QNX Software Systems开发的两个重要的嵌入式技术.它们在嵌入式系统领域具有广泛的应用和卓越的表现. QNX OS是一个实时操作系 ...

  2. QNX操作系统信息传递

    一.QNX消息概述 QNX消息可以分为同步消息和异步消息.异步(脉冲)消息主要体现的是一种通知机制,同步消息主要是说消息在传递过程需要双方相互配合的过程. 二.QNX消息传递几个基本概念 1.频道与链 ...

  3. 调用其他服务器上的函数 消息传递,QNX操作系统信息传递

    二.脉冲信号 在一些场合客户端不能阻塞等待服务器应答,例如中断处理函数,时钟函数,等.这种非阻塞的消息传递我们称之为脉冲.脉冲信号有如下特点: 1)有效传递40位数据(8位脉冲码,32位数据) 2)对 ...

  4. qnx 镜像文件_一种基于Hypervisor的QNX操作系统启动方法及装置与流程

    本发明涉及计算机领域,尤其涉及一种基于Hypervisor的QNX操作系统启动方法及装置. 背景技术: 基于Hypervisor的QNX是一种商用的遵从POSIX规范,常用用在汽车及路由器上,QNX是 ...

  5. Android的intent之间复杂参数的传递

    2019独角兽企业重金招聘Python工程师标准>>> Intent是Activity与Activity之间,Activity与Service之间传递参数的介质 Intent传递的参 ...

  6. Palabos用户手册翻译及学习(四)非本地操作的数据处理器和块之间的耦合

    非本地操作的数据处理器和块之间的耦合 Palabos用户文档 的第十六章 (#)前言 原始文档 Dynamics classes and data processors are the nuts an ...

  7. linux qnx 开发平台,QNX学习笔记之QNX Momentics IDE开发工具使用笔记

    使用tftp,串口连接Target,下载内核 1.uboot的使用 1) 采用串口,波特率为115200, 采用QNX M IDE默认的设置,按任意键,即可进入uboot 2) 常用的命令有: set ...

  8. 通过System.Management获取操作系统信息

    引用System.Management.dll 我们能轻松获取系统信息.看如下代码: 1: ObjectQuery oq = new ObjectQuery("SELECT * FROM W ...

  9. OPK修改操作系统信息 --oobe.xml

    OPK修改操作系统信息<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /& ...

最新文章

  1. ubuntu/linuxmint如何添加和删除PPA源
  2. mysql的基本数据类型_mysql基本数据类型(mysql学习笔记三)
  3. Windows下用命令行查找文件for命令的运用
  4. 自动化测试特定区域滑动_自动化用户特定实体的访问控制
  5. RNN调试错误:lstm_cell = tf.contrib.rnn.core_rnn_cell.BasicLSTMCell(lstm_size) 方法已失效
  6. Android开发笔记(十四)圆弧进度动画CircleAnimation
  7. 5.1 百度寻人 ios解析   和     天气预报解析
  8. pywinauto简单示例
  9. C++:数组的输入、排序与去重操作
  10. 如何将两段音乐合并成一段?
  11. 侠客工具盒 v5.0 build 0313 bt
  12. 支付宝小程序中使用阿里字体图标
  13. 红米k30pro开发者选项
  14. 微信小程序实现运动步数排名与发布个人动态服务器部署
  15. PPP再迎风口 相关概念股表现格外抢眼
  16. Onedrive如何同步文件夹
  17. 在群晖NAS上搭建WordPress动态网站并实现外网访问
  18. Xcode自带的instrument中的Automation实现自动化测试简单使用
  19. 解析learn the python3 the hard way里的ex43
  20. 钉钉总裁叶军与智办事CEO胡志强就企业绩效数字化进行了深度对谈

热门文章

  1. DDL(数据定义语言)
  2. 使用zerotier planet自建服务器客户端配置方法
  3. 工商银行分布式服务C10K场景的解决方案
  4. 重磅:小米正式宣告港股上市!雷军冲击中国首富,更有工号前100员工成亿万富翁...
  5. 孔维滢 20171010110《面向对象程序设计(java)》第十周学习总结
  6. H5资源本地化策略 - iOS
  7. H5与原生IOS通讯之一 (DSBrige)
  8. 【领域泛化】论文介绍《Learning to balance specificity and invariance for in and out of domain generalization》
  9. Pomelo Connector
  10. 格子披风背后,他们正用代码改变世界!