IPC对象的持续性

  • 随进程持续 :一直存在直到打开的最后一个进程结束。(如pipe和FIFO)
  • 随内核持续 :一直存在直到内核自举(内核自举就是把主引导记录加载到内存,并跳转执行这段内存)或显示删除(如System V消息队列、共享内存、信号量)
  • 随文件系统持续 :一直存在直到显示删除,即使内核自举还存在。(POSIX消息队列、共享内存、信号量如果是使用映射文件来实现)

消息队列

  • 消息队列提供了一种从一个进程向另外一个进程发送一块数据的方法
  • 每个数据块都被认为是有一个类型,接受者进程接受的数据块可以有不同的类型值
    • 管道所传输的数据是基于字节流的,数据与数据之间是没有边界的,所以通常称管道为流管道;接受数据的时候,遵守先进先出的原则。
    • 消息队列传输的数据块是有类型的,通常把成为消息,消息与消息之间是有边界的;接受数据的时候,不一定要按照顺序的方式来接受(不一定要先进先出)
  • 消息队列也有管道一样的不足,就是每个消息的最大长度是有限的(MSGMAX),每个消息队列的总的字节数是有限的(MSGMNB),系统上消息队列的总数也是有一个上限(MSGMNI)

IPC对象数据结构

  内核为每个IPC对象维护一个数据结构

  1. struct ipc_perm {
  2. uid_t cuid; /* creator user ID */
  3. gid_t cgid; /* creator group ID */
  4. uid_t uid; /* owner user ID */
  5. gid_t gid; /* owner group ID */
  6. unsigned short mode; /* r/w permissions */
  7. };

消息队列结构

  1. struct msqid_ds {
  2. struct ipc_perm msg_perm;
  3. msgqnum_t msg_qnum; /* no of messages on queue */
  4. msglen_t msg_qbytes; /* bytes max on a queue */
  5. pid_t msg_lspid; /* PID of last msgsnd(2) call */
  6. pid_t msg_lrpid; /* PID of last msgrcv(2) call */
  7. time_t msg_stime; /* last msgsnd(2) time */
  8. time_t msg_rtime; /* last msgrcv(2) time */
  9. time_t msg_ctime; /* last change time */
  10. };

消息队列在内核中的表示

消息队列函数

msgget

  1. 头文件
  2. #include <sys/types.h>
  3. #include <sys/ipc.h>
  4. #include <sys/msg.h>
  5. int msgget(key_t key, int msgflg);
  6. 作用:
  7. 创建或打开一个消息队列
  8. 参数:
  9. key 某个消息队列的名字
  10. msgflg 9个权限标志构成,它们的用法和创建文件时使用的模式标志是一样的
  11. 返回值:
  12. 成功 返回一个非负整数,即消息队列的标识码
  13. 失败 -1

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/ipc.h>
  6. #include <sys/msg.h>
  7. #define ERR_EXIT(m) \
  8. do \
  9. { \
  10. perror(m); \
  11. exit(EXIT_FAILURE); \
  12. } while (0)
  13. int main(int argc, char const *argv[])
  14. {
  15. int msgid;
  16. // 如果存在就打开,不存在就创建
  17. // msgid = msgget(1234,0666 | IPC_CREAT);
  18. // 如果不存在就创建,存在打开就报错
  19. // msgid = msgget(1234,0666 | IPC_CREAT | IPC_EXCL);
  20. //IPC_PRIVATE实际上等于0,当key为IPC_PRIVATE时,会创建一个新的消息队列,不能被其他进程共享;父子进程、兄弟进程可以共享,因为可以获取到msqid
  21. // msgid = msgget(IPC_PRIVATE,0666 | IPC_CREAT | IPC_EXCL);
  22. //指定了IPC_PRIVATE后,可以不加IPC_CREAT | IPC_EXCL
  23. // msgid = msgget(IPC_PRIVATE,0666);
  24. //如果消息队列已存在,可以直接打开
  25. msgid = msgget(1234,0);
  26. if(msgid == -1)
  27. ERR_EXIT("msgget");
  28. printf("msget success, msgid=%d\n!",msgid);
  29. return 0;
  30. }

msgctl

  1. int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  2. 作用:
  3. 控制消息队列
  4. 参数:
  5. msqid msgget函数返回的消息队列标识码
  6. cmd 将要采取的动作
  7. IPC_STAT : msgid_ds结构中的数据设置为消息队列的当前关联值
  8. IPC_SET : 在进程有足够权限的前提下,把消息队列的当前关联值设置为msgid_ds数据结构中给出的值
  9. IPC_RMID : 删除消息队列
  10. buf
  11. 返回值:
  12. 成功 0
  13. 失败 -1

IPC_RMID

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <sys/msg.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. int main(int argc, char const *argv[])
  7. {
  8. int msqid;
  9. msqid = msgget(1234, 0);
  10. if(msqid == -1)
  11. {
  12. perror("msgget error");
  13. exit(EXIT_FAILURE);
  14. }
  15. printf("msqid : %d\n",msqid);
  16. msgctl(msqid,IPC_RMID,NULL);
  17. return 0;
  18. }

IPC_STAT

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <sys/msg.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. int main(int argc, char const *argv[])
  7. {
  8. int msqid;
  9. msqid = msgget(1234, 0);
  10. if(msqid == -1)
  11. {
  12. perror("msgget error");
  13. exit(EXIT_FAILURE);
  14. }
  15. printf("msqid : %d\n",msqid);
  16. struct msqid_ds buf;
  17. msgctl(msqid,IPC_STAT,&buf);
  18. printf("mode : %o\n",buf.msg_perm.mode);
  19. printf("bytes : %ld\n",buf.__msg_cbytes);
  20. printf("number : %lu\n",buf.msg_qnum);
  21. printf("msgmnb : %lu\n",buf.msg_qbytes);
  22. return 0;
  23. }

IPC_SET

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <sys/msg.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. int main(int argc, char const *argv[])
  7. {
  8. int msqid;
  9. msqid = msgget(1234, 0);
  10. if(msqid == -1)
  11. {
  12. perror("msgget error");
  13. exit(EXIT_FAILURE);
  14. }
  15. printf("msqid : %d\n",msqid);
  16. struct msqid_ds buf;
  17. msgctl(msqid,IPC_STAT,&buf);
  18. sscanf("600", "%o", (unsigned int*)&buf.msg_perm.mode);
  19. msgctl(msqid, IPC_SET, &buf);
  20. printf("mode : %o\n",buf.msg_perm.mode);
  21. return 0;
  22. }

其它

ipcs - 查看当前已打开的消息队列

ipcrm -S|-s key|semid - 删除打开的消息队列

ipcrm -q msqid - 删除打开的消息队列

ipcrm -Q 键 - 删除打开的消息队列(只能用于键不为0的)

第二十五章 system v消息队列(一)的更多相关文章

  1. 第二十六章 system v消息队列(二)

    msgsnd int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 作用: 把一条消息添加到消息队列中 参数: msqi ...

  2. 第6章 System V消息队列

    6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...

  3. 第二十七章 system v消息队列(三)

    消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...

  4. 第二十九章 System V共享内存

    共享内存数据结构 共享内存函数 shmget int shmget(key_t key, size_t size, int shmflg); 功能: 用于创建共享内存 参数: key : 这个共享内存 ...

  5. 进程间通信 System V 消息队列

    1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...

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

    System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...

  7. 利用System V消息队列实现回射客户/服务器

    一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...

  8. UNIX环境高级编程——system V消息队列

    unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的.     消息队列(也叫报文队列)客服了这些缺点:     消息队列就是一个消息的链表.     可以把消 ...

  9. Gradle 1.12用户指南翻译——第二十五章. Scala 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

随机推荐

  1. C++常用库函数(1)

    Hello,疯狂的杰克由于大家见面了哦! 今天,给大家介绍一篇很有内涵的文章:C++常用库函数 1.缓冲区操作函数 函数名:memchr 函数原型:void  *memchr(const void * ...

  2. ES 32 - Elasticsearch 数据建模的探索与实践

    目录 1 什么是数据建模? 2 如何对 ES 中的数据进行建模 2.1 字段类型的建模方案 2.2 检索.聚合及排序的建模方案 2.3 额外存储的建模方案 3 ES 数据建模实例演示 3.1 动态创建 ...

  3. kotlin系列文章 --- 3.条件控制

    if表达式 一个if语句包含一个布尔表达式和一条或多条语句 // 基础用法 var max = a if (a<b) max = b // 加上else var max: Int if(a> ...

  4. 关于SpringBoot 1.x和2.x版本差别

    有点小差别 基本上基于SpringBoot的代码不需要改动,但有些配置属性和配置类,可能要改动,改动原因是 配置和类的更新或者是改名一般正常的MVC,数据库访问这些都不需要改动,下面按照本书章节说明区 ...

  5. DDR3 DDR4 FPGA实现

    基于7系列.virtex6等xilinx器件的MIG ip核设计DDR3/4读写控制器,以及基于arria 10器件的DDR4读写控制:DDR3/4的设计,设计的关键点是提高DDR3/4的访问效率,目 ...

  6. MQTT介绍与使用

    物联网是新一代信息技术的重要组成部分,也是“信息化”时代的重要发展阶段.其英文名称是:“Internet of things(IoT)”.顾名思义,物联网就是物物相连的互联网.这有两层意思:其一,物联 ...

  7. Cocos2d-x入门之旅[2]精灵

    精灵就是cocos是屏幕上移动的对象,能被我们控制,比如我们HelloWorld场景的这个图片就是精灵(Sprite) 怎么才算精灵?你能控制它的,就是一个精灵,否则就只是一个节点(Node) 准确的 ...

  8. Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝

    Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝ 教程 Xadmin安装方法: settings.py 的配置

  9. 动态扩容lvm逻辑卷的操作记录

    在进行动态扩容LVM逻辑卷的之前,先看这篇文章:https://www.cnblogs.com/huhyoung/p/9689776.html.以下是我实操记录. 在上班期间,测试经理突然找我,能不能 ...

  10. 超级好用的c#解析JSON

    分享c# 一款非常好用的操作Json的dll,litjson VS2017 NuGet 搜索litjson,如下图: 例子: 在项目中新建一个txt文本文件,内容如下: [ { , "use ...