QNX中进程间通信(IPC)之Signal篇

本文介绍在QNX系统中如何为应用程序设置信号处理函数,以便在接收到特定信号时执行相应操作,同时避免直接在信号处理函数中调用Photon函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


主要内容翻译自QNX开发文档,根据自己理解翻译,错误之处在所难免,目的还是提供给大家对照阅读,我自己也写了一些代码,抽空后继也会放上

 

 

<!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Cambria; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1073741899 0 0 159 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; text-indent:10.0pt; mso-char-indent-count:2.0; line-height:150%; mso-pagination:none; font-size:12.0pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} h2 {mso-style-priority:9; mso-style-qformat:yes; mso-style-link:"标题 2 Char"; mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; text-indent:10.0pt; mso-char-indent-count:2.0; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:16.0pt; font-family:"Cambria","serif"; mso-ascii-font-family:Cambria; mso-ascii-theme-font:major-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:major-fareast; mso-hansi-font-family:Cambria; mso-hansi-theme-font:major-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:major-bidi; mso-font-kerning:1.0pt;} p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {mso-style-priority:34; mso-style-unhide:no; mso-style-qformat:yes; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; text-indent:21.0pt; mso-char-indent-count:2.0; line-height:150%; mso-pagination:none; font-size:12.0pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} span.2Char {mso-style-name:"标题 2 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 2"; mso-ansi-font-size:16.0pt; mso-bidi-font-size:16.0pt; font-family:"Cambria","serif"; mso-ascii-font-family:Cambria; mso-ascii-theme-font:major-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:major-fareast; mso-hansi-font-family:Cambria; mso-hansi-theme-font:major-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:major-bidi; font-weight:bold;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:1010639450; mso-list-template-ids:67698717;} @list l0:level1 {mso-level-text:%1; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:21.25pt; text-indent:-21.25pt;} @list l0:level2 {mso-level-text:"%1/.%2"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:49.6pt; text-indent:-1.0cm;} @list l0:level3 {mso-level-text:"%1/.%2/.%3"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:70.9pt; text-indent:-1.0cm;} @list l0:level4 {mso-level-text:"%1/.%2/.%3/.%4"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:99.2pt; text-indent:-35.4pt;} @list l0:level5 {mso-level-text:"%1/.%2/.%3/.%4/.%5"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:127.55pt; text-indent:-42.5pt;} @list l0:level6 {mso-level-text:"%1/.%2/.%3/.%4/.%5/.%6"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:163.0pt; text-indent:-2.0cm;} @list l0:level7 {mso-level-text:"%1/.%2/.%3/.%4/.%5/.%6/.%7"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:191.35pt; text-indent:-63.8pt;} @list l0:level8 {mso-level-text:"%1/.%2/.%3/.%4/.%5/.%6/.%7/.%8"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:219.7pt; text-indent:-70.9pt;} @list l0:level9 {mso-level-text:"%1/.%2/.%3/.%4/.%5/.%6/.%7/.%8/.%9"; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:255.1pt; text-indent:-85.0pt;} @list l1 {mso-list-id:1850556317; mso-list-type:hybrid; mso-list-template-ids:-1459326628 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l1:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:none; mso-level-number-position:left; margin-left:45.0pt; text-indent:-21.0pt; font-family:Wingdings;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

如果应用程序需要处理信号 (signal) ,你需要设置信号处理函数 (signal handler) 。你不能在信号处理函数中调用 Photon 函数的原因是由于 widget library 是非可重入和信号安全的。

为了绕开这个问题, Photon library 包含了一个信号处理函数,你注册一个信号处理函数后, Photon 会稍后调用:

l  Photon signal handler 返回

l  所有当前 widget 的处理都已完成

注意 :当你使用这种信号处理方式,你将得不到严格的实时性,这是因为信号处理函数不是立即调用的。

1.1     Adding a signal-processing function

调用 PtAppAddSignalProc() 函数来添加信号处理函数,典型应用与:

l  应用程序初始化函数

l  某窗口的设置函数

需要包含 <signal.h> 文件。

 

PtAppAddSignalProc() 函数语法如下:

int PtAppAddSignalProc( PtAppContext_t app,

                        sigset_t const *set,

                        PtSignalProc_t func,

                        void *data);

参数列表:

app

应用程序上下文。

set

可能导致信号处理函数被调用的信号集合的指针。使用 sigemptyset() sigaddset() 函数建立该集合。更多信息参见 QNX Neutrino Library Reference

func

信号处理函数。参见 Photon Library Reference 中的 PtSignalProc_t

data

函数所传递数据。

PtAppAddSignalProc() 返回 0 表示成功, -1 表示失败。

信号处理函数原型如下:

int signalProcFunctions (int signum

                         void *data);

参数列表如下:

signum

处理的信号数量。

data

PtAppAddSignalProc() 函数中指定的 data 参数。

如果你希望保留该信号,返回 Pt_CONTINUE ,删除信号返回 Pt_END( 如果函数还被其他信号注册,在其他信号产生时将再次被调用 )

1.2     Removing a signal-processing function

删除信号处理函数:

调用 PtAppRemoveSignal() 删除单个或所有信号处理函数、数据对。

在信号处理函数中返回 Pt_END ,如果函数被多次注册,将会保持安装状态。
### QNX IPC Client Server 实现与用法 #### 客户端服务器模型概述 在QNX操作系统中,客户端-服务器架构是一种常见的进程间通信(IPC)模式。这种设计允许不同程序之间相互通信并交换数据。对于QNX而言,其IPC机制特别之处在于消息传递是通过内存复制完成的[^1]。 #### 创建服务端 要创建一个简单的服务器,在QNX环境中通常会执行如下操作: 1. 初始化连接请求监听器; 2. 接收来自客户端的消息; 3. 处理接收到的数据; 4. 向客户端发送响应。 下面是一个基本的服务端代码框架: ```c #include <stdio.h> #include <stdlib.h> #include <sys/neutrino.h> int main(void){ int rcvid; struct _pulse pulse; // 设置脉冲接收者ID name_attach_t *attach = NameAttach(NULL, "my_server"); while(1){ // 阻塞等待直到有消息到达 if ((rcvid = MsgReceivePulse(0, &pulse, sizeof(pulse), NULL)) != -1){ printf("Received Pulse Code:%d\n", pulse.code); // 对应处理逻辑... // 发送回复给客户端 MsgReply(rcvid, EOK, NULL, 0); } } // 清除资源 NameDetach(attach); return EXIT_SUCCESS; } ``` #### 构建客户端 相对应地,构建客户端应用程序涉及以下几个方面的工作: 1. 连接到目标服务器; 2. 发送命令或查询到该服务器; 3. 获取返回的结果。 这里给出一段用于建立连接并向上述例子中的`my_server`发送信号量通知的简单客户端代码片段: ```c #include <stdio.h> #include <unistd.h> #include <sys/neutrino.h> int main(){ int coid; // 建立连接对象句柄 coid = ConnectAttach(ND_LOCAL_NODE, 0, name_open("my_server"),_NTO_SIDE_CHANNEL, 0); // 准备好要发出的通知结构体 struct _pulse msg_pulse; memset(&msg_pulse, 0, sizeof(msg_pulse)); msg_pulse.type = _NETMSG_PULSE; msg_pulse.code = MY_CUSTOM_CODE; // 将准备好的通知发出去 MsgSendPulse(coid, 0, (char*)&msg_pulse,sizeof(msg_pulse)); // 断开连接 connect_detach(coid); return 0; } ``` 以上展示了如何利用QNX特有的高效消息传递功能来搭建简易版的客户机/服务器应用实例。值得注意的是,实际开发过程中还需要考虑更多细节如错误处理、并发控制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值