三种IPC的共同特征

1.标识符和键

每个内核中的IPC结构都用一个非负整数的标识符加以引用。当一个IPC结构被创建,以后又被删除时,与这种结构相关的标识符连续加1,直至达到一个整型数的最大值,然后又回转到0

标识符是IPC对象的内部名,为使多个合作进程能够在同一IPC对象上会合,需要提供一个外部名,即键

无论何时创建IPC结构,都应指定一个键,键的数据类型是基本系统数据类型key_t.键由内核变换成标识符

2.权限结构

XSI IPC为每一个IPC结构设置了一个ipc_perm结构。该结构规定了权限和所有者。

struct ipc_perm

{

  uid_t uid;

  gid_t gid;

  ...

};

3.优点和缺点

1)IPC结构没有访问计数,当没有进程访问时,也不会自动删除

2)IPC结构在文件系统中没有名字

3)IPC不使用文件描述符,不能对它们使用多路转接I/O函数:select和poll

IPC随进程持续、随内核持续以及随文件系统持续的定义:
1. 随进程持续:IPC一直存在到打开IPC对象的最后一个进程关闭该对象为止。如管道和有名管道;
2. 随内核持续:IPC一直持续到内核重新自举(即重启)或者显式删除该对象为止。如消息队列、信号灯以及共享内存等;
3. 随文件系统持续:IPC一直持续到显示删除该对象为止。

消息队列

(1)消息缓冲区(msgbuf)

我们在这里要介绍的第一个数据结构是msgbuf结构,可以把这个特殊的数据结构看成一个存放消息数据的模板,它在include/linux/msg.h中声明,描述如下:

/* msgsnd 和msgrcv 系统调用使用的消息缓冲区*/

struct msgbuf {

long mtype;         /* 消息的类型,必须为正数 */

char mtext[1];      /* 消息正文 */

};

注意:对于消息数据元素(mtext),不要受其描述的限制。实际上,这个域(mtext)不仅能保存字符数组,而且能保存任何形式的任何数据。这个域本身是任意的,因为这个结构本身可以由应用程序员重新定义:

struct my_msgbuf {

long    mtype;          /* 消息类型 */

long    request_id;     /* 请求识别号 */

struct client info;    /* 客户消息结构 */

};

我们看到,消息的类型还是和前面一样,但是结构的剩余部分由两个其它的元素代替,而且有一个是结构。这就是消息队列的优美之处,内核根本不管传送的是什么样的数据,任何信息都可以传送。

但是,消息的长度还是有限制的,在Linux中,给定消息的最大长度在include/linux/msg.h中定义如下:

#define MSGMAX 8192    /* max size of message (bytes) */

消息总的长度不能超过8192字节,包括mtype域,它是4字节长。

(2)消息结构(msg)

内核把每一条消息存储在以msg结构为框架的队列中,它在include/ linux/msg.h中定义如下:

struct msg {

struct msg *msg_next;   /* 队列上的下一条消息 */

long msg_type;          /*消息类型*/

char *msg_spot;         /* 消息正文的地址 */

short msg_ts;           /* 消息正文的大小 */

};

注意:msg_next是指向下一条消息的指针,它们在内核地址空间形成一个单链表。

(3)消息队列结构(msgid_ds)

当在系统中创建每一个消息队列时,内核创建、存储及维护这个结构的一个实例。

/* 在系统中的每一个消息队列对应一个msqid_ds 结构 */

struct msqid_ds {

struct ipc_perm msg_perm;

struct msg *msg_first;    /* 队列上第一条消息,即链表头*/

struct msg *msg_last;    /* 队列中的最后一条消息,即链表尾 */

time_t msg_stime;        /* 发送给队列的最后一条消息的时间 */

time_t msg_rtime;            /* 从消息队列接收到的最后一条消息的时间 */

time_t msg_ctime;             /* 最后修改队列的时间*/

ushort msg_cbytes;          /*队列上所有消息总的字节数 */

ushort msg_qnum;          /*在当前队列上消息的个数 */

ushort msg_qbytes;        /* 队列最大的字节数 */

ushort msg_lspid;           /* 发送最后一条消息的进程的pid */

ushort msg_lrpid;           /* 接收最后一条消息的进程的pid */

};

消息队列具有队列的基本特征,也具有其独特的性质。在消息队列中,入列称为发送消息,出列称为接收消息。除此之外,消息队列还具有以下特征。

1)消息队列中的消息是有类型的。同一类型的消息放在同一个消息链表中,多个消息链表形成一个消息队列。在发送一条消息时,可以指定消息类型;在接收进程中,可以按照该消息类型从消息队列中获取数据。在实际应用中,可以多个应用共用一个队列,用消息类型区分不同的应用。
2)消息队列中的消息按照发送的顺序排队,对于相同类型的消息,先进入消息队列的消息先被接收。
消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法。与有名管道比较起来,消息队列的优点在独立于发送与接收进程,这减少了在打开与关闭有名管道之间同步的困难。

参考:

http://blog.chinaunix.net/uid-197233-id-3083911.html

【APUE】进程间通信之消息队列的更多相关文章

  1. [转]Linux进程间通信——使用消息队列

    点击此处阅读原文 另收藏作者ljianhui的专栏初学Linux 下面来说说如何使用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linu ...

  2. 练习--LINUX进程间通信之消息队列MSG

    https://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 继续坚持,或许不能深刻理解,但至少要保证有印象. ~~~~~~~~~~~~~~ 消息队 ...

  3. Linux进程间通信——使用消息队列

    下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管道   一.什么是消息队列 消息队列提 ...

  4. 进程间通信--POSIX消息队列

    相关函数: mqd_t mq_open(const char *name, int oflag); mqd_t mq_send(mqd_t mqdes, const char *msg_ptr, si ...

  5. Linux进程间通信(消息队列/信号量+共享内存)

    写在前面 不得不说,Deadline果真是第一生产力.不过做出来的东西真的是不堪入目,于是又花了一早上重写代码. 实验内容 进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系 ...

  6. Linux进程间通信之消息队列

    本文依据以下思路展开,首先从宏观上阐述消息队列的机制,然后以具体代码为例进一步阐述该机制,最后试着畅想一下该通信机制潜在的应用. 消息队列是在两个不相关进程间传递数据的一种简单.高效方式,她独立于发送 ...

  7. Linux进程间通信(二) - 消息队列

    消息队列 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点(管道请查阅我的另一篇文章 ...

  8. linux 进程间通信之 消息队列

    消息队列就是一个消息的链表. 能够把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程能够向中依照一定的规则加入新消息.有读权限的进程则能够读走消息. 读走就没有了.消息队列是 ...

  9. linux下的进程间通信之消息队列

    概念: 进程彼此之间可以通过IPC消息进行通信.进程产生的每条消息都被发送到一个IPC消息队列中,这条消息一直存放在队列中,直到另一个进程将其读走为止. 优点:可以通过发送消息来几乎完全避免命名管道的 ...

随机推荐

  1. Promise 理解与使用

    个人觉得这篇博客写的非常详细且易懂,推荐给小伙伴们~ https://www.cnblogs.com/lvdabao/p/es6-promise-1.html#!comments

  2. AT2663 Namori Grundy

    题目描述: luogu 题解: 好多细节,比如说每个点有且仅有一条入边. 所以说这个图一定是一个基环外向树. 考虑只是一个环的情况,我们可以发现,当环长为偶数时我们可以$01$交替染色,但环长为奇数时 ...

  3. 深入Linux内核架构——进程管理和调度(下)

    五.调度器的实现 调度器的任务是在程序之间共享CPU时间,创造并行执行的错觉.该任务可分为调度策略和上下文切换两个不同部分. 1.概观 暂时不考虑实时进程,只考虑CFS调度器.经典的调度器对系统中的进 ...

  4. CSS---基础外部样式表

    <link rel="stylesheet" type="text/css" href="style.css" media=" ...

  5. 第三讲:post-processsing with vcs+ files

    1,dump wave  by system function $vcdpluson(level_number,module_instance,....|net_or_reg) $vcdplusoff ...

  6. Linux基础(Ubuntu)

    更换apt源为清华源 1.备份 /etc/apt/sources.list 2.vim 编辑 /etc/apt/sources.list 添加 deb http://mirrors.tuna.tsin ...

  7. Django reverse函数

    1.总urls.py内容如下: from django.contrib import admin from django.urls import path from django.conf.urls ...

  8. 【转】错误: ORA-01591: 锁被未决分布式事务处理 7.2.428982 持有--解决方案

    SQL 错误: ORA-01591: 锁被未决分布式事务处理 7.2.428982 持有 01591. 00000 -  "lock held by in-doubt distributed ...

  9. Android开发——Accessibility机制实现模拟点击(微信自动抢红包实现)

    1. 何为Accessibility机制 许多Android使用者因为各种情况导致他们要以不同的方式与手机交互.对于那些由于视力.听力或其它身体原因导致不能方便使用Android智能手机的用户,And ...

  10. 66. No EntityManager with actual transaction available for current thread【从零开始学】

    [从零开始学习Spirng Boot-常见异常汇总] 具体异常信息: org.springframework.dao.InvalidDataAccessApiUsageException: No En ...