一.概述                                                   

System V三种IPC:消息队列,信号量,共享内存。这三种IPC最先出现在AT&T System v UNIX上面,并遵循XSI标准,有时候也被称为XSI IPC。

本文先探讨消息队列:

1.消息队列允许进程以消息的形式交换数据。读写都是针对整条消息,不能读写消息的一部分,不像管道那样可以以流的形式读写任意字节。

2.消息队列除了包含数据外,还有一个整数来表示该消息的类型。读取消息的时候即可以按照先进先出方式读取,也可以按照消息类型来读取。

二.函数接口                                            

1.创建一个消息队列

 #include <sys/msg.h>

 int msgget(key_t key, int msgflg);

key:是一个整数,该函数会将key转换成一个IPC标识符。key有3种方法定义:1.手动随意指定一个整数。2.把IPC_PRIVATE当作key传入,系统会自动生成。3.用ftok()函数。

msgflg:指定该消息的权限,跟文件的权限控制类似。

2.发送消息

 #include <sys/msg.h>

 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msqid:用msget()获取的id。

mgsp:存储消息的结构指针,下面的mtype就是自定义的消息类型,mtext是消息数据。

 struct msgbuf {
                long mtype;       /* message type, must be > 0 */
                ];    /* message data */
            };

msgsz:消息的大小,对应上面msgbuf里面的mtext。

msgflg:控制消息发送时异常状况,如消息队列满。

3.接收消息

 #include <sys/msg.h>

 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msqid:用msget()获取的id,或者已知的消息ID。

msgp,msgsz:同msgsnd()。

msgtyp:接收消息的类型,即msgbuf里面的mtype。但还有别的用法:

如果为0,就获取队列中第一个可用消息。

大于0,获取相同类型消息的第一个,即mtype。

小于0,获取等于或小于mtype的绝对值第一个消息。等会我们一一做实验。

msgflg:同msgsnd()。

4.消息控制

 #include <sys/msg.h>

 int msgctl(int msqid, int cmd, struct msqid_ds *buf);

cmd:有3个选项,IPC_STAT,IPC_SET,IPC_RMID。前2个是获取和设置msgid对应的消息结构体,最后一个是删除消息队列。

三.简单的例子                                        

1.创建消息队列

 /**
  * @file msg_create.c
  */

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/msg.h>

 void err_exit(const char *err_msg)
 {
     printf("%s error\n", err_msg);
     exit();
 }

 int main(void)
 {
      | IPC_CREAT);
     )
         err_exit("msgget()");

     printf("create msg_id:%d\n", msg_id);

     ;
 }

2.发送消息

 /**
  * @file msg_send.c
  */

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/msg.h>

 #define MAX_BUFFER 1024

 typedef struct
 {
     long msg_type;
     char msg_text[MAX_BUFFER];
 } msg_t;

 void err_exit(const char *err_msg)
 {
     printf("%s error\n", err_msg);
     exit();
 }

 int main(int argc, char *argv[])
 {
     )
     {
         printf(]);
         exit();
     }

     ]);
     msg_t send_msg;
     ];
     int text_len = strlen(text);

     send_msg.msg_type = atoi(argv[]);
     memcpy((void *)send_msg.msg_text, text, text_len);

     ) == -)
         err_exit("msgsnd()");

     ;
 }

3.接收消息

 /**
  * @file msg_recv.c
  */

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/msg.h>

 #define MAX_BUFFER 1024

 typedef struct
 {
     long msg_type;
     char msg_text[MAX_BUFFER];
 } msg_t;

 void err_exit(const char *err_msg)
 {
     printf("%s error\n", err_msg);
     exit();
 }

 int main(int argc, const char *argv[])
 {
     )
     {
         printf(]);
         exit();
     }

     ]);
     msg_t recv_msg;
     ]);

     ) == -)
         err_exit("msgrcv()");

     printf("receive:%s\n", recv_msg.msg_text);

     //if (msgctl(msg_id, IPC_RMID, 0) == -1)
     //    err_exit("msgctl()");

     ;
 }

四.实验                                                   

1.创建消息,编译执行msg_create.c,用ipcs -q查看消息:

可以看到:msqid就是用IPC_PRIVATE当作key传入,系统会自动生成的,msqid=262144等会接收消息要用。perms是我们代码设置的权限,此时的消息字节和消息数都是0。

2.发送消息,编译执行msg_send.c,并发消息,用ipcs -q查看消息:

上面./mes_send后面依次是:刚刚创建的消息队列id,消息类型,消息数据。

接下来,我们再继续发送1条1类型消息,2条2类型消息,2条3类型消息,等会接收消息做实验。

现在我们有6条消息了。

3.接收消息,编译msg_recv.c。我们主要来实验msgrcv()里面的msg_type参数。即该文件的第36行代码。

3.1:当msg_type等于0时,获取队列中第一个可用消息。

可以看到,1234就是我刚刚第一次发送到该队列的消息。

3.2:当msg_type大于0,获取具有相同类型的第一个消息:

上面我们获取的是3类型的消息,接收的刚好是第一次发送3号消息的haha。

3.3:当msg_type小于0,获取等于或小于msg_type绝对值的第一个消息:

上面,-3的绝对值是3,而队列中存在最先放进去的消息是1号消息22222(本来是1号的1234,刚刚我们做实验时读取走了,所以剩下它第一)。1小于3,所以1号消息被读取。

4.消息队列的删除,msg_recv.c里面第41行代码,如果放开后编译执行,收到一条消息后整个队列全部删除。

System V IPC(1)-消息队列的更多相关文章

  1. System V IPC 之消息队列

    消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...

  2. 四十九、进程间通信——System V IPC 之消息队列

    49.1 System V IPC 介绍 49.1.1 System V IPC 概述 UNIX 系统存在信号.管道和命名管道等基本进程间通讯机制 System V 引入了三种高级进程间通信机制 消息 ...

  3. Linux 系统编程 学习:04-进程间通信2:System V IPC(1)

    Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...

  4. Linux 系统编程 学习:05-进程间通信2:System V IPC(2)

    Linux 系统编程 学习:05-进程间通信2:System V IPC(2) 背景 上一讲 进程间通信:System V IPC(1)中,我们介绍了System IPC中有关消息队列.共享内存的概念 ...

  5. 第3章 System V IPC

    3.1 概述 System V IPC 包含:System V消息队列.System V信号量.System V共享内存. 3.2 key_t 键和 ftok函数 这三种类型的System V IPC ...

  6. 《Unix网络编程》卷2 读书笔记 第3章- System V IPC

    1. 概述 三种类型的System V IPC:System V 消息队列.System V 信号量.System V 共享内存区 System V IPC在访问它们的函数和内核为它们维护的信息上共享 ...

  7. 从并发处理谈PHP进程间通信(二)System V IPC

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  8. System V IPC 之共享内存

    IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 ...

  9. System V IPC

    1.概述 System V IPC共有三种类型:System V消息队列.System V 信号量.System V 共享内存区. System V IPC操作函数如下: 2.key_t键和ftok函 ...

随机推荐

  1. VirtualBox-Linux系统安装增强功能

    我们在安装之前,必须得先安装好它所需要的依赖包,不然安装过程必定会出现错误! 一.安装依赖包 #yum install kernel-headers #yum install kernel-devel ...

  2. GJM : Python简单爬虫入门 (一) [转载]

    版权声明:本文原创发表于 [请点击连接前往] ,未经作者同意必须保留此段声明!如有侵权请联系我删帖处理! 为大家介绍一个简单的爬虫工具BeautifulSoup BeautifulSoup拥有强大的解 ...

  3. Struts1 中提交中文表单到ActionForm后出现乱码问题的原因及处理方法

    问题: 在你所有页面设置的编码都是utf-8的情况下仍然会出现中文乱码现象. 一.乱码出现原因 由于Struts框架直接把表单数据发送给了ActionForm,所以这里面没有对HttpRequestS ...

  4. 详解Javascript 函数声明和函数表达式的区别

    Javascript Function无处不在,而且功能强大!通过Javascript函数可以让JS具有面向对象的一些特征,实现封装.继承等,也可以让代码得到复用.但事物都有两面性,Javascrip ...

  5. JavaScript实现HTML5烟花特效

    烟花效果如下(请使用支持HTML5的浏览器查看):点击这里查看效果:http://keleyi.com/keleyi/phtml/html5/14.htm 源代码如下: ;}</style> ...

  6. 使用XmlHelper添加节点C#代码

    接着上一篇:http://keleyi.com/a/bjac/ttssua0f.htm在前篇文章中,给出了C# XML文件操作类XmlHelper的代码,以及使用该类的一个例子,即使用XmlHelpe ...

  7. 【iScroll源码学习03】iScroll事件机制与滚动条的实现

    前言 想不到又到周末了,周末的时间要抓紧学习才行,前几天我们学习了iScroll几点基础知识: 1. [iScroll源码学习02]分解iScroll三个核心事件点 2. [iScroll源码学习01 ...

  8. swift学习笔记之-类和结构体

    //类和结构体 import UIKit //类和结构体 /* 1.枚举enum.结构体struct和String.Array.Dictionary类型,都属于值传递类型,被赋值给新的常量或变量时传递 ...

  9. 新建WEB前端开发技术交流群---期待你的加入

    这几天创建了一个前端开发的技术交流群,面向的对象主要包括正在学习前端开发的和即将步入前端开发行列的小伙伴儿,主要是为大家提供一个共同学习,共同进步的开放平台.无论你现在是在自学中,还是在培训中,甚至是 ...

  10. iOS 3DES加密解密(一行代码搞定)

    3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三次DES加密算法.由于计 ...