• QNX Message Passing,一个让人头秃的 IPC BUG


    问题描述

    QNX系统中 Client 与 Server 通过 QNX Message Passing 进行进程间通信。正式开发前,写过测试程序 (Client),和 Server 通信一切正常。但把同样的代码拷贝到正式的 Client 中,结果发现调用 MsgSend() 后无响应,pidin 显示 Client 处于 REPLY PENDING 的状态。

    几番尝试,发现一个让人很难接受的事实:只能在 Client 的主线程中调用 MsgSend() 才能收到 Server 的回复,如果在 Client 的对等线程中调用MsgSend(),则会因为收不到 Server 的回复而 Pending。

    问题分析

    测试程序能正常工作,所以起初怀疑是 Client 的问题。面对庞大的 Client,始终没想到突破口。甚至曾一度怀疑是否是 QNX 的系统限制,MsgSend() 只能在主线程中调用,官网文档翻了一圈并没有发现这样的限制。自己写了个 IPC Server 来测试,发现并没有这个问题。

    Client Server 结果
    测试程序,主线程中调用 MsgSend() 正式 Server OK
    正式 Client,对等线程中调用 MsgSend() 正式 Server REPLY PENDING
    正式 Client,对等线程中调用 MsgSend() 简化版测试 Server OK

    最后不得不怀疑起 Server,莫非 Server 端有什么机制能检测到消息是发自主线程还是对等线程,然后只回复来自主线程的 IPC 请求?

    一个典型的 IPC Server 示例代码如下:

    While(1) {
       int rcvid = MsgReceive(chid, &recvBuf, sizeof(recvBuf), NULL);
       /* … process the request based on recvBuf … */
       MsgReply(rcvid, EOK, &replyBuf, sizeof(replyBuf)); // reply to unblock the IPC client
    }

    如果是从 Client 的主线程发送来的消息,rcvid 是一个很小的数字,如 1, 3, 5… 如果是从Client 的对等线程发送来的消息,rcvid 是一个大于 65535 的数字,如 65538, 65540, 65542… 

    让人意外的是 Server 用了一个 int16_t 来保存 rcvid,直接导致后续的 MsgReply() 无法正确的将消息回给 Client,从而导致 Client 一直处于 REPLY PENDING 状态。

    Reference

    • http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.sys_arch/topic/ipc_Robust.html  
  • 相关阅读:
    JavaFx初探
    TraceView总结
    sprintf,你知道多少?
    C/C++:多个.cpp文件包括同一个.h头文件定义方法
    Android中Preference的使用以及监听事件分析
    Android系统默认Home应用程序(Launcher)的启动过程源码分析
    升级、备份红帽PaaS openshift 上的 wordpress
    几种开源分词工具的比較
    设计模式奠基石——UML关系转化为代码
    Windows 7系统安装MySQL5.5.21图解
  • 原文地址:https://www.cnblogs.com/tengzijian/p/qnx-message-passing-ipc-bug-in-peer-thread.html
Copyright © 2020-2023  润新知