主要内容翻译自QNX开发文档,根据自己理解翻译,错误之处在所难免,目的还是提供给大家对照阅读,我自己也写了一些代码,抽空后继也会放上
除了支持消息传递方式 (message) 来同步之外, Photon 也支持脉冲 (pulse) 。一个进程如果仅仅为了通知对方而不需要回复的情况下,可以使用 pulse 。例如,在 server 发送消息可能导致双方互锁 (SEND-blocked) 引起的死锁 (deadlocked) 的情况下,应该使用 pulse 。
一个 Photon pulse 由一个 PtAppAddInput() 中 pid 参数的 PID 标识, PID 对你的应用程序而言是本地的。如果你希望接收另一应用程序发送的 pulse ,你必须使用 PtPulseArm() 函数来“瞄准 (arm) ”对方。该函数创建一个可以通过消息发送给其他进程的 PtPulseMsg_t 对象。这样其他进程就可以通过 MsgDeliverEvent() 函数发送 pulse 。
注意 :
在 QNX Neutrino OS 6 中, PtPulseMsg_t 是一个 sigevent 类型的结构。 msg.sigev_value.sival_int 位对应的 _NOTIFY_COND_MASK 被清除,但发送 pulse 的应用程序可以进行设置。更多内容参见 QNX Neutrino Library Reference 。
PtPulseArm() (Photon Library Reference 中有说明 ) 函数参数中包含一个 sigevent 结构类型变量。 PtPulseArmFd() 和 PtPulseArmPid() 兼容于早期 QNX Neutrino OS 和 Photon microGUI 版本。
对于 pulse 接收端 ( 我们称为 server) ,需要做如下工作:
1) 创建 pulse 。
2) 瞄准 (arm)pulse.
3) 发送 pulse 消息到发送 pulse 端 ( 我们称之为 client) 。
4) 注册 pulse 处理函数。
5) 如有必要,发送 pulse 到自身。
6) 当 pulse 不需要时删除。
注意 :退出前请通知发送端停止发送 pulse 。
调用 PtAppCreatePulse() 函数创建一个 Photon pulse :
pid_t PtAppCreatePulse( PtAppContext_t app,
int priority );
参数列表:
app
PtAppContext_t 结构类型标识的应用程序上下文地址,使用 NULL 表示使用默认上下文。
priority
pulse 优先级,使用 -1 表示调用程序使用的优先级。
PtAppCreatePulse() 返回一个非零整数表示的 pulse process ID 。
Arm 一个 pulse 填充一个可以被大部分 QNX Neutrino 调用使用的 sigevent 结构。
注意 :
多个 client 发出相同的 pulse 是正常的,尽管 server 不知道是由哪个进程发出的。
PtPulseArm() 函数原型如下:
int PtPulseArm( PtAppContext_t app,
pid_t pulse,
struct sigevent *msg );
参数如下:
app
当前应用上下文地址。 ( 一般设置为 NULL) 。
pulse
由 PtAppCreatePulse() 创建的 pulse 。
msg
函数创建的 pulse message 指针,我们应该将其传递到 client 。
函数返回 pulse message ID ,后面将会用到。
发送 pulse message 到 client ,如下:
l 对于 resource manager ,使用 ionotify() :
ionotify (fd, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT,
&pulsemsg);
l 对于其他类型进程,可以使用 MsgSendv() :
/* Create your own message format: */
msg.pulsemsg = pulsemsg;
MsgSendv (connection_id, &msg, msg_parts, &rmsg, rmsg_parts);
注册 pulse 的消息处理与 message 的处理基本相同。将 PtAppCreatePulse() 返回的 pulse ID 作为参数传递到 PtAppAddInput() 即可。
Rcvid 参数没有必要与 pulse ID 相同:在 _NOTIFY_DATA_MASK 位上与 pulse ID 相同 ( 参见 QNX Neutrino Library Reference 中 ionotify() 部分 ) ,但是其余位自 Neutrino pulse 接收。
如果应用程序需要发送 pulse 到自身,可以使用 PtAppPulseTrigger() 函数:
int PtAppPulseTrigger( PtAppContext_t app,
pid_t pulse );
两个参数分别是应用程序上下文和 PtAppCreatePulse() 返回的 pulse ID 。
以下是接收 Photon pulse 的例子。该例子打开一个消息队列 (message queue)( 默认使用 /dev/mqueue/testqueue) ,设置一个 pulse ,并且在从消息队列读取到内容时使用 mq_notify() 给自身一个 pulse 。
/* Standard headers */ #include
发送 pulse 的 Photon 应用程序 (Client 端 ) 需要做以下工作:
l 使用一个 input handler 处理 Server 发送的 pulse 消息。使用 input handler 来处理包含 pulse 消息在内的各种消息,并且通知发送方停止发送 pulse 。注:保存消息中的 rcvid 值来发送 pulse ,你可能需要用来发送该 pulse 。
l 调用 MsgDeliverEvent() 发送 pulse 。