前言:前面讨论了信号、管道的进程间通信方式,接下来将讨论消息队列。

  一、系统V IPC

  三种系统V IPC:消息队列、信号量以及共享内存(共享存储器)之间有很多相似之处。

  每个内核中的 I P C结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符
( i d e n t i f i e r )加以引用。

  无论何时创建I P C结构(调用m s g g e t、 s e m g e t或s h m g e t) ,都应指定一个关键字(k e y),关
键字的数据类型由系统规定为 k e y _ t,通常在头文件< s y s / t y p e s . h >中被规定为长整型。关键字由
内核变换成标识符。

  以上简单介绍了IPC,对接下来介绍的消息队列、信号量和共享内存有助于理解。

  二、消息队列

  1、简介

  消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。我们将称消息队列为
“队列”,其标识符为“队列 I D”。 m s g g e t用于创建一个新队列或打开一个现存的队列。 m s g s n d
用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际
数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给 m s g s n d。 m s g r c v用于从
队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。

  2、函数介绍

  • ftok函数

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'
功能:生成一个key(键值)

  • msgget函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

功能:创建或取得一个消息队列对象
返回:消息队列对象的id 同一个key得到同一个对象
格式:msgget(key,flag|mode);
flag:可以是0或者IPC_CREAT(不存在就创建)
mode:同文件权限一样

  • msgsnd函数

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:将msgp消息写入标识为msgid的消息队列
msgp:
struct msgbuf {
long mtype; /* message type, must be > 0 */消息的类型必须>0
char mtext[1]; /* message data */长度随意
};

msgsz:要发送的消息的大小 不包括消息的类型占用的4个字节
msgflg: 如果是0 当消息队列为满 msgsnd会阻塞
如果是IPC_NOWAIT 当消息队列为满时 不阻塞 立即返回

返回值:成功返回id 失败返回-1

  • msgrcv函数

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

功能:从标识符为msgid的消息队列里接收一个指定类型的消息 并 存储于msgp中 读取后 把消息从消息队列中删除
msgtyp:为 0 表示无论什么类型 都可以接收
msgp:存放消息的结构体
msgsz:要接收的消息的大小 不包含消息类型占用的4字节
msgflg:如果是0 标识如果没有指定类型的消息 就一直等待
如果是IPC_NOWAIT 则表示不等待

  • msgctl函数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象

  程序2-2将简单演示消息队列:

  ---  snd.c  ---

#include "my.h"

typedef struct{
long type;
char name[];
int age;
}Msg; int main()
{
key_t key = ftok("/home/liudw",'');
printf("key:%x\n",key); int msgid = msgget(key,IPC_CREAT|O_WRONLY|);
if(msgid<)
{
perror("msgget error!");
exit(-);
} Msg m;
puts("please input your type name age:");
scanf("%ld%s%d",&m.type,m.name,&m.age);
msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),); return ;
}

  ---  rcv.c  ---

#include "my.h"

typedef struct{
long type;
char name[];
int age;
}Msg; int main()
{
key_t key = ftok("/home/liudw",'');
printf("key:%x\n",key); int msgid = msgget(key,O_RDONLY);
if(msgid<)
{
perror("msgget error!");
exit(-);
} Msg rcv;
long type;
puts("please input type you want!");
scanf("%ld",&type); msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,);
printf("rcv--name:%s age:%d\n",rcv.name,rcv.age); msgctl(msgid,IPC_RMID,NULL);
return ;
}

  运行演示:

  三、详解ftok函数 

  • ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。
  • 该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
  • proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;

  为了验证以上观点,对程序2-2稍作修改,将路径和proj_id修改:

  程序3-1如下:

  ---  snd.c  ---

#include "my.h"

typedef struct{
long type;
char name[];
int age;
}Msg; int main()
{
key_t key = ftok("/home",'a');
printf("key:%x\n",key); int msgid = msgget(key,IPC_CREAT|O_WRONLY|);
if(msgid<)
{
perror("msgget error!");
exit(-);
} Msg m;
puts("please input your type name age:");
scanf("%ld%s%d",&m.type,m.name,&m.age);
msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),); return ;
}

  ---  rcv.c  ---

#include "my.h"

typedef struct{
long type;
char name[];
int age;
}Msg; int main()
{
key_t key = ftok("/home",'a');
printf("key:%x\n",key); int msgid = msgget(key,O_RDONLY);
if(msgid<)
{
perror("msgget error!");
exit(-);
} Msg rcv;
long type;
puts("please input type you want!");
scanf("%ld",&type); msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,);
printf("rcv--name:%s age:%d\n",rcv.name,rcv.age); msgctl(msgid,IPC_RMID,NULL);
return ;
}

  运行演示如下图:

 

  总结:主要介绍了进程间通信的消息队列,有疑问可以留言,一定即时解答。

详解linux进程间通信-消息队列的更多相关文章

  1. 详解linux进程间通信-信号

    前言:之前说看<C++ Primer >暂时搁浅一下,迷上公司大神写的代码,想要明白,主要是socket.进程间通信! 知道进程间通信:信号.信号量.管道.消息队列.共享内存(共享存储), ...

  2. Linux进程间通信-消息队列(mqueue)

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...

  3. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  4. Linux进程间通信—消息队列

    四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...

  5. linux进程间通信-消息队列

    一 消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构. 我们可以通过发送消息来避免命名管道的 ...

  6. Linux 进程间通信 消息队列 实现两个进程间通信

    例子: 通过消息队列实现两个进程间通信,一个进程从终端输入数据,通过消息队列发送,另一个进程通过消息队列接收数据 文件1 创建进程1 终端输入通过消息队列发送数据 #include <stdio ...

  7. linux进程间通信消息队列:msgsnd: Invalid argument

    今天写了个消息队列的小测试程序结果send端程序总是出现:msgsnd: Invalid argument,搞了半个小时也没搞明白,后来查资料发现我将(st_msg_buf.msg_type = 0; ...

  8. Linux 进程间通信 消息队列

    1.特点: 消息队列是IPC对象的一种 消息队列由消息队列ID来唯一标识 消息队列就是一个消息的列表.用户可以在消息队列中添加消息.读取消息等. 消息队列可以按照类型来发送/接收消息(消息的类型是正整 ...

  9. 详解linux进程间通信-管道 popen函数 dup2函数

    前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...

随机推荐

  1. 剑指Offer——腾讯+360+搜狗校招笔试题+知识点总结

    剑指Offer--腾讯+360+搜狗校招笔试题+知识点总结 9.11晚7:00,腾讯笔试.选择题与编程.设计题单独计时. 栈是不是顺序存储的线性结构啊? 首先弄明白两个概念:存储结构和逻辑结构. 数据 ...

  2. FFmpeg源代码简单分析:结构体成员管理系统-AVClass

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  3. Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup

    今天在给客户做环境迁移,安装包完成后按惯例打补丁,但在打补丁的时候却报错了,错误如下 最开始怀疑第一个打6是不是不对,毕竟N久没碰2011了忘的差不多了,后来下了个rollup1居然也打不上,根据这个 ...

  4. 06 intent flag三种属性

    flag属性可以看做和写在清单文件中的启动模式一样 但效果有一定差别 1,FLAG_ACTIVITY_SINGLE_TOP:启动模式里的SingleTop一致  如果X启动模式设置为FLAG_ACTI ...

  5. scala学习笔记5 (隐式转化/参数/类)

    隐式转化: 隐式参数: 隐式类:

  6. 初探linux子系统集之timer子系统(三)

    因为现在的linux虽然还是可以使用低精度的timer,但是趋势是高精度hrtimer,所以上一篇试着翻译一下hrtimer的一些介绍,翻译的不是很好,看来英语还得好好学习啊,下面还是好好学习下lin ...

  7. (NO.00004)iOS实现打砖块游戏(四):砖块类的实现

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用Xcode打开之前SpriteBuilder创建的项目,我们现 ...

  8. J2EE进阶(二)从零开始之Struts2

    J2EE进阶(二)从零开始之Struts2 以前自己总是听说什么SSH框架,不明觉厉.现在自己要重整旗鼓,开始系统性的学习SSH框架了.首先开始Struts2的学习.其实自己之前参与过Struts2项 ...

  9. 1025. PAT Ranking (25)

    题目如下: Programming Ability Test (PAT) is organized by the College of Computer Science and Technology ...

  10. TOMCAT数据源连接配置

    /* *本文档简单介绍系统使用TOMCAT6.0数据源方式连接数据库的配置方法: *1,系统环境:  gdczsam4.0 + Tomcat6.0 + JDK1.5 + SQL Server2008 ...