二.脉冲信号

在一些场合客户端不能阻塞等待服务器应答,例如中断处理函数,时钟函数,等。这种非阻塞的消息传递我们称之为脉冲。脉冲信号有如下特点:

1)有效传递40位数据(8位脉冲码,32位数据)

2)对发送者而言是非阻塞的

3)可以像其他消息一样被接受

4)脉冲会排队,只要接受者不是阻塞等待脉冲。

1.接受脉冲消息

可以利用MsgReceive函数接受消息,跟普通消息没有区别,但是不能用MsgReply,毕竟脉冲是异步的,不需要应答。MsgReceivePulse函数专门用来处理脉冲。如果程序调用MsgReceive返回值是0表明接受到的是一个脉冲信号。

例如:

#include

rcvid = MsgReceive (chid, …);

if (rcvid == 0) {   // it's a pulse

// determine the type of pulse

// handle it

} else {            // it's a regular message

// determine the type of message

// handle it

}

2.脉冲结构提体定义:

struct _pulse {

uint16_t        type;

uint16_t        subtype;

int8_t          code;

uint8_t         zero [3];

union sigval    value;

int32_t         scoid;

};

type和subtype为0,code和value组成40bits发送码。code指定脉冲类型,value携带数据。

value是一个联合体

union sigval {

int     sival_int;

void    *sival_ptr;

};

经常看到的典型应用是:

#include

rcvid = MsgReceive (chid, …

if (rcvid == 0) {   // it's a pulse

// determine the type of pulse

switch (msg.pulse.code) {

case    MY_PULSE_TIMER:

// One of your timers went off, do something

// about it...

break;

case    MY_PULSE_HWINT:

// A hardware interrupt service routine sent

// you a pulse.  There's a value in the "value"

// member that you need to examine:

val = msg.pulse.value.sival_int;

// Do something about it...

break;

case    _PULSE_CODE_UNBLOCK:

// A pulse from the kernel, indicating a client

// unblock was received, do something about it...

break;

// etc...

} else {            // it's a regular message

// determine the type of message

// handle it

}

3.脉冲接收函数

有时候我们只需要接受脉冲信号,例如,某个时刻,我们接受到客户端请求去做某事,但是我们不能立即给客户端作出响应,可能是我们在做一个长时间的硬件操作。在这种情况下,我们通常会给硬件设定一个定时器或则脉冲信号,当有事情发生。如果我们把服务器设计为经典的无线循环等待消息的模式,我们需要等待各种请求,这种设计是合理的,毕竟,服务器必须在一个时间服务多个线程。但是这样我们必须限制服务器数量。

在这种情况下,我们必须选择只是接受脉冲信号,而不是常规信号,这就是MsgReceivePulse函数的作用。

#include

int MsgReceivePulse (int chid,

void *rmsg,

int rbytes,

struct _msg_info *info);

4.如何设计需要接受脉冲信号和普通信号的服务器

通常我们设计一个线程池服务MsgReceive函数,对客户端请求作出响应。必须控制线程池线程数量,一些线程必须阻塞,等待脉冲到达,让线程池线程阻塞的典型方式是调用MsgReceivePulse函数,确保客户端请求会被及时察觉。

5.MsgDeliverEvent()函数的使用

之前我们提到发送消息时候的等级制度,有些情况我们需要打破,例如,客户端给服务器发送消息,服务器不能立刻应答而客户端不想等待。遇到这种情况,正确的做法是,告诉客户端,请求一段时间后会得到处理客户端得以继续运行,一旦服务器完成任务,服务器需要一些方式告诉客户端,请求完成。在发送等级的时候提到客户端不能给服务器发送消息,可能会导致死锁,如果同一时间客户端给服务器也发送消息请求。

解决这个问题需要多步操作。

1)客户端创建一个 struct sigevent 并且填充

2)客户端给服务器发送消息

3)服务器接受到消息存下结构体信息,以及Receive ID,立即对客户端应答。

4)客户端继续运行

5)当服务器完成任务调用 MsgDeliverEvent()通知客户端任务完成

int

MsgDeliverEvent (int rcvid,

const struct sigevent *event);

event服务器不需要作修改

rcvid是服务器从客户端接收的。当服务器给客户端应答,这个id将失去意义。

另外MsgDeliverEvent是非阻塞函数。

三、频道创建时候的标志位

_NTO_CHF_FIXED_PRIORITY

接受线程优先级不因为发送线程的优先级而发生改变。

_NTO_CHF_UNBLOCK

当客户端试图解除阻塞的时候,内核发送脉冲给服务器(_PULSE_CODE_UNBLOCK )

_NTO_CHF_THREAD_DEATH

当阻塞在频道内的一个线程死亡,内核发送脉冲(_PULSE_CODE_THREADDEATH )

_NTO_CHF_SENDER_LEN

内核把客户端消息的长度作为消息的一部分传递给服务器(srcmsglen)

_NTO_CHF_REPLY_LEN

内核把客户端应答消息缓存的长度作为消息的一部分传递给服务器(srcmsglen)

_NTO_CHF_COID_DISCONNECT

当进程内的所有连接都被终止了

_NTO_CHF_UNBLOCK详解:

我们知道,在消息传递中,为了保证可靠性,当

客户端向服务器发送消息时,客户端是被“阻塞”(BLOCK)住的。这种状态,要一直到服务器应答了以后才会被开放。这就造成了一个问题,有时候,如果服务器还没有应答,而客户端又希望从阻塞中恢复,那又怎么办呢? 最常见的,比如用户CTRL-C了客户端进程,按POSIX标准,一个SIGINT应该被发送到客户端进程,而客户端进程如果没有特别处理的话,应该被SIGINT终止。那么,如果这时,客户端正好在阻塞状态中,会怎么样呢? 如果客户端进程,就这样突然凭空消失的话,服务器端会混乱,因为服务器端的程序,是建立在客户端被阻塞的情形下的。试想一下,如果客户端突然消失了,而服务器端又要MsgRead(),或是MsgWrite()会发生什么事呢? 为了防止服务器端发生这种混乱,QNX规定如果一个进程,正REPLY

BLOCK在别的进程上的时候,它不能自动脱离BLOCK状态;相反地,如果进程有什么理由要退出BLOCK状态,系统会先给服务器端发送一个 “UNBLOCK”脉冲,好象是说“REPLY BLOCK中的xx线程希望脱离阻塞状态”;而由服务器自己判断应该如何处理。服务器端可以在自己内部数据结构做出整理后,选择MsgError(rcvid,

EINTR);以解除客户端的阻塞状态;也可以什么也不做,不理睬这个脉冲,这样客户端就不能退出BLOCK状态。有时候你会在QNX遇到Ctrl-c但进程却没有退出的情况,这就是因为进程正被阻塞在一个服务器上,而服务器没有正确处理

UNBLOCK PAULSE的结果。

四、同步问题

即使我们创建频道的时候设置了_NTO_CHF_UNBLOCK参数。实际情况下依然有一个同步问题需要我们处理。想象一下,服务器多个线程阻塞在MsgReceive函数,等待消息或者脉冲,这时候,客户端发送一个消息,其中一个线程接收了并开始工作。这期间,客户端希望解除阻塞状态,那么内核发送一个解除阻塞的脉冲消息。服务器其他线程接收到这个脉冲。这样第一个和第二个线程会发生竞争,如果第二个线程给客户端应答那么它会收到客户端对应的一些信息,这时候第一个线程应答客户端,可能这已经是客户端第二次请求了。另外一种情况是,第一个线程先应答,那么可能是把客户端第二次请求的阻塞解除了。通常解决这个问题的办法是用一个互斥锁。MsgReceive之后加锁MsgReply之前解锁。

五、消息在网络中的传递

55/5<12345

调用其他服务器上的函数 消息传递,QNX操作系统信息传递相关推荐

  1. QNX操作系统信息传递

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

  2. QNX操作系统信息传递-qnx任务之间的消息传递信息传递

    转载:https://blog.csdn.net/xjhhjx/article/details/77139457 一.QNX消息概述 QNX消息可以分为同步消息和异步消息.异步(脉冲)消息主要体现的是 ...

  3. php怎么上传函数,PHP单文件上传原理及上传函数的封装操作示例

    搜索热词 @H_404_0@本文实例讲述了PHP单文件上传原理及上传函数的封装操作.分享给大家供大家参考,具体如下: @H_404_0@表单: @H_404_0@0.PHP: 无标题文档 请选择您要上 ...

  4. java 线程 函数_java – 从后台线程调用主线程上的函数

    更新 我已经更新了这个问题,使用建议的SwingWorker类包含Java实现的源代码,以实现与Objective-C示例相同的结果.希望这将有助于未来的冒险家. Document myDoc = . ...

  5. 无法加载服务器指定地图,用javascript调用iserver服务器上的地图不显示

    我用javascript调用我自己在iserver上发布的地图不显示,但是调用官网教程上的原始地图实例可以显示,代码使用的是教程中快速入门的代码,我修改了地图的目标坐标系为EPSG:3857,并且在调 ...

  6. SpringSecurity(二十)---OAuth2:实现资源服务器(上)资源服务器搭建以及直接调用授权服务器模式

    一. 前言 本章将讨论如何使用Spring Security实现一个资源服务器,资源服务器是管理用户资源的组件.另外,学习本章有个前提,需要先把前面搭建授权服务器的相关文章先给阅读,否则可能后面出现的 ...

  7. 普通的PHP上传到云函数,php封装上传函数代码示例

    php封装上传函数代码示例 发布时间:2020-05-14 17:16:12 来源:亿速云 阅读:184 作者:Leah 今天小编就为大家带来一篇有关php封装上传函数的文章.小编觉得挺实用的,为此分 ...

  8. fMRI质量预检查与服务器批量处理:时间点、体素尺寸批量审查与Dpabi(DPARSFA)服务器上无GUI无弹窗处理脑功能影像(附matlab脚本)

    | 图源-slice | 工具:dpabi5.0, spm12, NIfTI_20140122(密码:iizk)      我们知道在进行fMRI预处理的时候,要求所有被试时间点相同,它将直接影响到s ...

  9. 执行远程服务器上的脚本失败?(环境变量引起的问题)

    我们在使用jenkins构建job时会调用远程服务器上的脚本,执行某项操作.有时因为脚本涉及到了环境变量,无法成功执行.解决这个问题的方法一直就是在脚本开始加入一行: source /etc/prof ...

最新文章

  1. 接口测试(postman jmeter)
  2. UEditor在线编辑器使用记录
  3. mysql5.1.6安装_mysql 5.1.6的安装启动
  4. 零基础学Android之常用控件
  5. C#中DataTable中的Compute方法使用收集
  6. 小程序采用mvvm设计模式_滴滴重磅开源跨平台统一 MVVM 框架 Chameleon
  7. 安卓中的@Nullable和NonNull(NotNull) 等 注释
  8. Palindrome Degree(hash的思想题)
  9. linux c编译 utf-8,在Linux C编程中使用Unicode和UTF-8
  10. LaTeX符号大全-基于lshort-zh-cn
  11. 计算几何之计算三角形的外接圆(三维)
  12. java 复制网页文字_网页文字复制不了?你这样做,全网文字任你免费复制!快get!...
  13. 斐讯k2虚拟服务器设置,斐讯K2调配设置
  14. 网易有道笔试题(2014届,2013.10北邮站)
  15. 【BZOJ4049】【Cerc2014】 Mountainous landscape 【凸包】【线段树】
  16. android16进制编辑器,16进制编辑器app
  17. 读书笔记: 经济学原理
  18. Mosquitto常用命令
  19. 中国上海人工智能CIMCAI世界第一完成两百万次AI验箱上亿次箱识别,成熟AI产品运行超7百万小时智慧港航智能化中国上海人工智能
  20. tkMapper的基本使用

热门文章

  1. 电脑C盘空间还很多,电脑却卡得飞起怎么办。
  2. 2017百度之星程序设计大赛 - 资格赛:1003 度度熊与邪恶大魔王
  3. STM32F103 扩展以太网口
  4. 用python生成动态樱花树
  5. 漫画图解python_80道漫画图解算法题汇总
  6. Debian 6.0安装igb驱动
  7. 在大厂入职三年已是老员工?大学教授:年轻人压力很大。。。
  8. 关于投篮的数学建模模型_投篮问题的数学建模[共10页]
  9. iOS小技巧总结,绝对有你想要的(持续更新)
  10. 流量卡设备状态已停用怎么开启_物联卡无故停机怎么办?最全操作指南点这里,亲测有效!...