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

一、系统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

#include

key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'

功能:生成一个key(键值)

msgget函数

#include

#include

#include

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"typedefstruct{longtype;char name[20];intage;

}Msg;intmain()

{

key_t key= ftok("/home/liudw",'6');

printf("key:%x\n",key);int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

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),0);return 0;

}

---  rcv.c  ---

#include "my.h"typedefstruct{longtype;char name[20];intage;

}Msg;intmain()

{

key_t key= ftok("/home/liudw",'6');

printf("key:%x\n",key);int msgid =msgget(key,O_RDONLY);if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg rcv;longtype;

puts("please input type you want!");

scanf("%ld",&type);

msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);

printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);

msgctl(msgid,IPC_RMID,NULL);return 0;

}

运行演示:

三、详解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"typedefstruct{longtype;char name[20];intage;

}Msg;intmain()

{

key_t key= ftok("/home",'a');

printf("key:%x\n",key);int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

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),0);return 0;

}

---  rcv.c  ---

#include "my.h"typedefstruct{longtype;char name[20];intage;

}Msg;intmain()

{

key_t key= ftok("/home",'a');

printf("key:%x\n",key);int msgid =msgget(key,O_RDONLY);if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg rcv;longtype;

puts("please input type you want!");

scanf("%ld",&type);

msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);

printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);

msgctl(msgid,IPC_RMID,NULL);return 0;

}

运行演示如下图:

 

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

linux 消息对lie_详解linux进程间通信-消息队列相关推荐

  1. linux环境下ps命令行,Linux下ps命令详解 Linux下ps命令的详细使用方法

    Linux下ps命令详解 Linux上进程有5种状态:1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不可运 ...

  2. linux的vi命令详解,Linux上Vi命令详解

    Linux下Vi命令详解 补充一点:在vi中使用命令的方法是:冒号+命令+回车,如:q 回车代表退出.================================================= ...

  3. linux中create命令详解,linux中 pmap 命令详解

    通过查看帮助,返回了如下信息: Usage: pmap [options] pid [pid ...] Options: -x, --extended show details -X show eve ...

  4. linux中which命令详解,Linux下which命令使用详解(转)

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索: which 查看可执行文件的位置. whereis 查看文件的位置. locate 配合数据库查看文件位置. f ...

  5. linux中的ps fx命令,Linux下ps命令详解 Linux下ps命令的详细使用方法

    Linux下ps命令详解 1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断 ...

  6. linux 命令行 time,详解Linux time 命令的使用

    1.命令简介 time 用于统计命令执行所消耗的时间及相关系统资源等信息.time 可以显示的资源有四大项,分别是: Time resources Memory resources IO resour ...

  7. linux怎么授权目录,详解Linux如何将一个文件夹的所有内容授权给某一个用户?...

    详解Linux如何将一个文件夹的所有内容授权给某一个用户? 发布时间:2020-09-14 15:23:51 来源:脚本之家 阅读:138 作者:冰阔落 栏目:服务器 [问题分析] 我们可以使用cho ...

  8. linux下awk命令详解,Linux文件处理awk命令-linux awk命令详解-嗨客网

    Linux文件处理awk命令详解教程 Linux awk命令说明 awk 是一个强大的文本分析工具,相对于 awk 有 3 个不同版本: awk.nawk 和 gawk,未作特别说明,一般指 gawk ...

  9. linux中jstack命令详解,Linux jstack命令详解

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息. 如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack ...

最新文章

  1. 把二叉搜索树转换为累加树
  2. 用ASP实现隐藏链接方法
  3. python 仿真_Python SimPy 仿真系列 (2)
  4. Ajax.ActionLink 辅助方法实现局部刷新
  5. 查看IIS日志 各大搜索引擎是否访问网站
  6. c语言while求a和b的和程序,数据结构实验1_C语言_输入集合A和B求并集、交集、差集(while +...
  7. iis html 空白页,IIS伪静态html静态页无法访问的解决方法
  8. MFC把 ListCtrl的数据导出到excel表格
  9. PMOS和NMOS的区分及导通方式
  10. 图像滤镜艺术---美颜相机之高级柔焦效果实现
  11. 百度分享在新闻列表页分享多篇文章
  12. CI框架使用PHPExcel生成快递面单
  13. limits.conf详解
  14. 文献分析工具Connected Papers
  15. C# 按Esc键关闭窗体
  16. 用debugserver+lldb代替gdb进行iOS远程动态调试
  17. Cygwin、Msys、MinGW、Msys2的区别与联系
  18. Arista 7500E系列交换机与SFP+/QSFP+光模块搭配方案
  19. .split()用法解释
  20. 百度智能云章淼:详解企业级七层负载均衡开源软件BFE

热门文章

  1. python学习的几篇文章推荐
  2. 通达信股票接口盘后数据下载流程是怎么样的?
  3. 我的世界怎么免费开一个服务器是正版,我的世界怎么开一个服务器
  4. 客似云来, 剪花布条
  5. python 拟合曲线并求参
  6. 利用红外发射遥控电器
  7. JavaWeb简单科研管理系统(jsp+Mysql8.0)
  8. Kerberos常见问题
  9. 非常好用的短视频解析除水印软件
  10. EF 框架的简介、发展历史;ORM框架概念