`

XSI IPC通信之消息队列

阅读更多
    消息队列是消息的链接表,存储在内核中,由消息队列标识符(或称为队列ID)标识。
    下表列出了影响消息队列的系统限制。其中“导出的”表示这种限制来源于其他限制。比如 Linux 系统中的最大消息数是根据最大队列数和队列中所允许的最大数据量来决定的,最大队列数又受 RAM 数量多少的影响,队列的最大字节数限制进一步限制了队列中将要存储的消息的最大长度。

    每个队列都关联有一个 msqid_ds 结构,它定义了队列的当前状态,至少支持下面这些字段,其中的 ipc_perm 结构见XSI IPC 相似特征介绍一节:
struct msqid_ds{
    struct ipc_perm    msg_perm;
    msgqnum_t          msg_qnum;        // # of messages on queue
    msglen_t           msg_qbytes;      // max # of bytes on queue
    pid_t              msg_lspid;       // pid of last msgsnd()
    pid_t              msg_lrpid;       // pid of last msgrcv()
    time_t             msg_stime;       // last-msgsnd() time
    time_t             msg_rtime;       // last-msgrcv() time
    time_t             msg_ctime;       // last-change time
    /* ... */
};

    msgget 函数用于创建一个新队列或打开一个现有队列。msgsnd 将新消息添加到队列尾端。msgrcv 用于从队列中取消息,但不一定是以先进先出次序取,也可以按消息的类型字段来取。msgctl 可对队列执行多种操作,它和后面章节中要介绍的另外两个与信号量及共享存储有关的函数 semctl 和 shmctl 都是 XSI IPC 的类似于 ioctl 的函数(亦即垃圾桶函数)。
#include <sys/msg.h>
int msgget(key_t key, int flag);
                      /* 返回值:若成功,返回消息队列 ID;否则,返回 -1 */
int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
                      /* 返回值:若成功,返回 0;否则,返回 -1 */
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
                      /* 返回值:若成功,返回消息数据部分的长度;否则,返回 -1 */
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
                      /* 返回值:若成功,返回 0;否则,返回 -1 */

    在XSI IPC 相似特征介绍一节中说明了将 key 变换成一个标识符的规则。
    使用 msgget 函数在创建新队列时,会初始化 msqid_ds 结构的下列成员。
    * ipc_perm 结构按XSI IPC 相似特征介绍一节中的所述进行初始化,其中的 mode 成员按 flag 中的相应权限位设置。
    * msg_qnum、msg_lspid、msg_lrpid、msg_stime 和 msg_rtime 都设置为 0。
    * msg_ctime 设置为当前时间。
    * msg_qbytes 设置为系统限制值。
    msgget 执行成功后返回的非负队列 ID 就可用于其他 3 个消息队列函数。
    msqsnd 函数将消息添加到队列尾端。每个消息包含一个正的长整型的字段、一个非负的长度 nbytes 以及对应于长度的实际数据字节数。msgsnd 中的 ptr 参数指向一个长整型数,它包含了正的整型消息类型,其后紧接着的是消息数据(若 nbytes 是 0 则无数据)。比如发送的最长消息是 512 字节,则可定义类似下列结构:
        struct mymesg{
            long mtype;         // positive message type
            char mtext[512];    // message data, of length nbytes
        };
    此时参数 ptr 就是一个指向 mymesg 结构的指针。接收者可以使用消息类型以非先进先出的次序取消息。要注意的是,有些平台同时支持 32 位和 64 位环境,这会影响到长整型和指针的大小。如果一个 32 位应用程序要经由管道或套接字与一个 64 位应用程序交换此结构,就会出问题。因为长整型的大小在 32 位环境中是 4 字节,而 64 位环境中则是 8 字节。在这种情况下,64 位应用程序的 mtype 字段的一部分会被 32 位应用程序视为 mtext 字段的组成部分,而 32 位应用程序的 mtext 字段的前 4 个字节会被 64 位应用程序解释为 mtype 字段的组成部分。即使对 IPC 系统调用的 32 位和 64 位版本具有不同的入口点,也存在潜在问题:当 64 位应用程序向 32 位应用程序发送消息时,如果它在 8 字节类型字段中设置的值大于 32 位应用程序中 4 字节类型字段可表示的值,那么 32 位应用程序在其 mtype 字段中得到的将是一个截短了的类型值。
    参数 flag 的值可以指定为 IPC_NOWAIT,这类似于文件 I/O 的非阻塞标志。若消息队列已满(或是队列中的消息总数或者队列中的字节总数等于了系统限制值),则指定 IPC_NOWAIT 可使 msgsnd 立即出错返回 EAGAIN,否则进程会一直阻塞到:有空间可以容纳要发送的消息;或者从系统中删除了此队列(此时会返回 EIDRM 错误);或者捕捉到一个信号,并从信号处理程序返回(此时会返回 EINTR 错误)。
    msgsnd 成功返回时,消息队列相关的 msqid_ds 结构也会随之更新。
    和 msgsnd 一样,msgrcv 中的 ptr 参数指向一个长整型数(其中存储的是返回的消息类型),其后跟随的是存储实际消息数据的缓冲区。nbytes 参数指定数据缓冲区的长度。若返回的消息长度大于 nbytes,而且在 flag 中设置了 MSG_NOERROR 位,则该消息会被自动截断,并丢弃多余的部分。如果消息太长时没设置此标志,则出错返回 E2BIG,但消息仍留在队列中。
    参数 type 可通过设置为下列值来指定想要哪一种消息。
    * 等于 0:返回队列中的第一个消息。
    * 大于 0:返回队列中消息类型为 type 的第一个消息。
    * 小于 0:返回队列中消息类型值不大于 type 绝对值的消息。如果这种消息有若干个,则取类型值最小的消息。
    type 值非 0 可用于以非先进先出次序读消息,例如可以用来代表优先级权值,或是表示客户进程的进程 ID 等。
    flag 参数也可指定为 IPC_NOWAIT 标志,以使操作不阻塞。这样,如果没有所指定类型的消息可用,则立即返回 -1,并将 errno 设置为 ENOMSG。没指定此标志时的阻塞情况同 msgsnd。
    msgrcv 执行成功时,msqid_ds 结构同样也会更新。
    msgctl 函数中的 cmd 参数指定了对 msqid 参数表示的队列要执行的下列命令之一。
    * IPC_STAT:取此队列的 msqid_ds 结构,并将其存放在 buf 指向的结构中。
    * IPC_SET:将字段 msg_perm.uid、msg_perm.gid、msg_perm.mode 和 msg_qbytes 从 buf 指向的结构复制到此队列关联的 msqid_ds 结构中。此命令只能由下列两种进程执行:一种是其有效用户 ID 等于 msg_perm.cuid 或 msg_perm.uid,另一种是具有超级用户特权的进程。只有超级用户才能增加 msg_qbytes 的值。
    * IPC_RMID:从系统中删除该消息队列以及仍在其中的所有数据。这种删除立即生效,仍在使用这个队列的其他进程在下一次试图操作此队列时将得到 EIDRM 错误。该命令也只能由上面提及的两种进程执行。注意,由于消息队列没有像文件一样维护引用计数器,所以继续操作被删除的队列的进程会出错返回,而不是像文件操作中需要等最后一个进程关闭了文件描述符后才能删除文件中的内容。后面要介绍的信号量机制也以这种方式处理其删除。
    这 3 条命令也可用于后文中要介绍的信号量和共享存储。
    最后要提醒的一点是,由于这种消息队列现在在速度方面已经和其他的 IPC 方式没有什么差别了,考虑到使用消息队列时遇到的问题,在新的应用程序中已经不再推荐使用了。
  • 大小: 8.2 KB
分享到:
评论

相关推荐

    linux 中 xsi ipc的简单使用

    XSI IPC包括了三种主要机制:消息队列、信号量和共享内存。这些机制允许进程之间进行同步和通信,是多线程和多进程编程中的关键组件。 **1. 消息队列** 消息队列是一种存储消息的数据结构,进程可以将消息发送到...

    liferay ipc porltet间通信DEMO

    本文将深入探讨"Liferay IPC(Inter-Portlet Communication)portlet间通信DEMO",并基于提供的`portlet.xml`文件来解析相关的配置信息。 1. **Liferay IPC简介** Liferay IPC机制使得不同的portlet能够共享数据和...

    XSI-ICE中文手册

    ### XSI-ICE中文手册关键知识点解析 #### 引言:理解XSI-ICE ...尽管存在一定的功能限制,但XSI-ICE仍以其独特的灵活性和强大功能,在专业领域占据了一席之地,是值得深入研究和熟练掌握的重要工具之一。

    XSI融和球插件

    【XSI融和球插件】是一款专为Softimage XSI(现在称为SILVERGUN)设计的强大特效工具,其在3D动画和视觉效果领域具有广泛的应用。这款插件以其独特的“融合球”技术著称,允许艺术家创建出高度复杂的形状和动态效果...

    利用semaphore实现shm进程通信

    其中,信号量结合共享存储区(ShareMemory)和消息传递统称为XSI IPC(扩展系统接口进程间通信),提供了一种高效的进程间通信机制。 #### 共享存储与信号量:一种高效IPC方案 文章进一步探讨了信号量与共享存储区...

    XSI的植物生成插件

    T-Gen是第一个完全整合进XSI的植物生成插件。超过100种造型和分布的参数,与XSI的曲线和基于节点的体系完美配合确保了用户创造自定性的植物时拥有强大的灵活性和无穷的可能性。你可以使用几乎所有的XSI工具对T-Gen...

    XSI经典插件emFluid3破解版

    XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版

    xml中的xmlns:、xmlns:xsi和xsi:schemaLocation.doc

    "XML中的xmlns、xmlns:xsi和xsi:schemaLocation详解" XML文档中的xmlns、xmlns:xsi和xsi:schemaLocation是三个重要的元素,分别用于定义XML文档的命名空间、XML schema实例和schemaLocation。 一、xmlns xmlns是...

    xsi_python

    字符串是 Python 中最基本的数据类型之一,用于存储文本信息。在 XSI 脚本中,字符串常用来处理文件路径、对象名称等。 **2.2.2 数字** Python 支持多种数字类型,包括整数、浮点数和复数等。这些数据类型在处理...

    Spring学习笔记3之消息队列(rabbitmq)发送邮件功能

    1. **MQ全称Message Queue**,即消息队列,它允许应用程序通过消息传递进行通信,而无需直接连接。 2. **生产者(Producer)**:负责发送消息到Exchange。 3. **Exchange**:根据预设的路由规则,将消息放入合适的队列...

    SPH.rar_SPH_SPH XSI_xsi sph plugin

    标题中的"SPH.rar_SPH_SPH XSI_xsi sph plugin"揭示了这是一个与流体模拟相关的软件插件,主要用于3D建模和动画软件Softimage XSI(也称为XSI)。SPH代表Smoothed Particle Hydrodynamics(平滑粒子流体动力学),这...

    ActiveMQ消息队列技术融合Spring过程解析

    ActiveMQ 消息队列技术融合 Spring 过程解析 ActiveMQ 消息队列技术融合 Spring 过程解析是当前 Java 企业级应用程序中一种常用的集成模式。通过本文,我们将详细介绍 ActiveMQ 消息队列技术融合 Spring 过程解析的...

    softimage xsi keygen

    Autodesk SoftImage 2013 的破解工具。 你懂的

    学习《高级Linux环境编程》读书笔记(APUE读书笔记)

    15. 进程间通信:详细讨论了几种UNIX进程间通信的机制,如管道、协同进程、命名管道(FIFO)、XSIIPC(包括消息队列、共享内存和信号量)以及这些机制在C/S模型中的应用比较。 16. 网络IPC:套接字:最后一章介绍了...

    XSI 2011 keygen downloader

    keygen downloader for xsi 2011 x 64. The way to finder keygen

    XSI 7 的破解方法

    XSI 7 的破解方法,图片视图,很直观,请多多支持,谢谢!!!

    Spring-ActiveMQ.rar_Spring Activemq_activemq_activemq spring

    在IT领域,消息队列(Message Broker)是一个重要的组件,它允许分布式系统中的不同部分通过异步通信来解耦和协调工作。ActiveMQ是Apache软件基金会的一个开源项目,它是Java消息服务(JMS)的一个实现,广泛应用于...

    linux-ipcs:Linux进程间通信(Inter-Process Communication)方式汇总

    XSI消息队列 XSI信号量 XSI共享内存 POSIX信号量 域套接字(Domain Socket) 信号(Signal) 互斥量(Mutex) 其中信号(signal)和信号量(semaphore)本质上并不算是进程间通信方式,应该是进程间同步的方式,但是也可以起到...

Global site tag (gtag.js) - Google Analytics