Linux下进程通讯消息队列

  MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已。MQ 是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。
  消息队列与 FIFO 很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从队列中读取信息。

1.查看消息队列命令

  1.查看消息队列:ipcs -q

[wbyq@wbyq ~]$ ipcs -q--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息
0xb8104ad9 1          wbyq       644        0            0
0xd2350093 2          wbyq       666        208          2

  2.查看消息队列限制信息:ipcs -lq

[wbyq@wbyq ~]$ ipcs -lq---------- 消息限制 -----------
系统最大队列数量 = 32000
最大消息尺寸 (字节) = 8192
默认的队列最大尺寸 (字节) = 16384

  3.查看消息队列详细信息:ipcs -q -i <msqid>

[wbyq@wbyq ~]$ ipcs -q -i 2消息队列 msqid=2
uid=1000   gid=1000   cuid=1000  cgid=1000  模式=0666
cbytes=208 qbytes=16384   qnum=2 lspid=10177    lrpid=10175
发送时间=Thu Apr 28 11:56:08 2022
接收时间=Thu Apr 28 11:56:08 2022
更改时间=Thu Apr 28 11:49:04 2022

  4.创建消息队列:ipcmk -Q

[wbyq@wbyq ~]$ ipcmk -Q
消息队列 id:4
[wbyq@wbyq ~]$ ipcs -q--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息
0xb8104ad9 1          wbyq       644        0            0
0xd2350093 2          wbyq       666        208          2
0x05ae2c01 4          wbyq       644        0            0

5.删除信号量:ipcrm -q <msqid>

[wbyq@wbyq ~]$ ipcrm -q 4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息
0xb8104ad9 1          wbyq       644        0            0
0xd2350093 2          wbyq       666        208          2

2.相关函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
函数功能:创建消息队列
形参:key 键值,ftok产生
     msgflg 标志 IPC_CREAT|0666
返回值:失败返回-1,成功返回msqid
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
函数功能: 将消息添加到队列中
形参:msqid msgget函数返回值
   msgp 消息内容数据,一般以结构体类型填充
      struct msgbuf {
            long mtype; /* 消息类型, 必须 > 0 */
            char mtext[1]; /消息数据/
            };
      注意:struct msgbuf必须自己重写,第一个参数long mtype必须指定,且>0,其他类型自定义
   msgsz 消息字节数,大小为:sizeof(struct msgbuf)-sizeof(mtype);
   msgflg 0当队列满时阻塞,直到消息写入成功
      IPC_NOWAIT 当队列满时不阻塞,立刻返回
      IPC_NOERROR 若发送的消息大于 size 字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。
返回值:成功返回0,失败返回-1;
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
函数功能:从队列中取出消息
形参:msqid msgget函数返回值
   msgp 存放读取到的消息内容
   msgsz 消息字节数,大小为:sizeof(struct msgbuf)-sizeof(mtype);
   msgtyp 消息类型:
       >0 接收对列中的第 1 个类型等于 msgtyp 的消息
       ==0 取出消息队列中的第一条消息
       <0 接收其类型小于或等于 msgtyp 绝对值的第 1 个最低类型消息
   msgflg 0 当队列空时阻塞,或者消息类型不匹配时阻塞
       IPC_NOWAIT 不阻塞,立刻返回
       IPC_NOERROR 若发送的消息大于 size 字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。
返回值:成功返回读取的字节数,失败返回-1;
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函数功能:控制函数
形参:msqid msgget函数返回值
   cmd 通常为 IPC_RMID 表示删除消息队列。
当删除消息队列时,则buf填NULL即可;

3.示例

  (1)创建消息队列,添加消息到队列

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
struct msgbuf
{long mtype;//消息类型,必须>0int cnt;char buff[100];
};
int main(int argc,char *argv[])
{if(argc!=4){printf("格式:./app <消息类型> <消息数据> <消息内容>\n");return 0;}key_t key=ftok("msgsnd.c", 1234);//生成键值if(key==-1){printf("生成键值失败err=%s\n",strerror(errno));return 0;}printf("key=%#x\n",key);int msqid=msgget(key,IPC_CREAT|0666);//创建消息队列if(msqid==-1){printf("创建消息队列失败err=%s\n",strerror(errno));return 0;}printf("msqid=%d\n",msqid);struct msgbuf msg;msg.mtype=atoi(argv[1]);//消息类型msg.cnt=atoi(argv[2]);//消息数据strcpy(msg.buff,argv[3]);//消息内容int msg_size=sizeof(msg)-sizeof(long);//消息大小,总大小-消息类型大小/*添加消息到队列*/int size=msgsnd(msqid,&msg,msg_size,0);if(size==-1){printf("写入消息失败err=%s\n",strerror(errno));}else printf("消息写入成功\n");return 0;
}

  (2)从队列中取消息

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
struct msgbuf
{long mtype;//消息类型,必须>0int cnt;char buff[100];
};
int main(int argc,char *argv[])
{if(argc!=2){printf("格式:./app <消息类型>\n");return 0;}key_t key=ftok("msgsnd.c", 1234);//生成键值if(key==-1){printf("生成键值失败err=%s\n",strerror(errno));return 0;}printf("key=%#x\n",key);int msqid=msgget(key,IPC_CREAT|0666);//创建消息队列if(msqid==-1){printf("创建消息队列失败err=%s\n",strerror(errno));return 0;}printf("msqid=%d\n",msqid);struct msgbuf msg;int msg_size=sizeof(msg)-sizeof(long);//消息大小long msgtyp=atoi(argv[1]);//要写读取的消息类型//从消息队列中取数据ssize_t size=msgrcv(msqid,&msg,msg_size,msgtyp,0);if(size==-1){printf("读取消息失败err=%s\n",strerror(errno));}else {printf("------------读取消息成功size:%ld----------------\n",size);printf("\tmtype=%ld\n",msg.mtype);printf("\tcnt=%d\n",msg.cnt);printf("\tbuff=%s\n",msg.buff);}return 0;
}

  (3)运行效果

Linux下进程通讯消息队列相关推荐

  1. [Linux学习]Linux下进程通讯之共享内存

    本文用两份代码,一个创建共享内存并向其中写入相关的数据,一个获取共享内存并读取其中的数据,下面上代码: server.c:获取共享内存,并向共享内存中写入数据 #include <sys/typ ...

  2. 【Linux】Linux进程间通信——共享内存/消息队列/守护进程

    文章目录 进程间通信--共享内存/守护进程 一, 共享内存 1. 共享内存概念 2. 共享内存使用 1. 共享内存使用步骤 2. 共享内存操作函数 3. 共享内存常用操作命令 4. 共享内存使用示例: ...

  3. linux进程间通信:POSIX 消息队列

    文章目录 基本介绍 相关编程接口 编程实例 消息队列通信实例 消息队列属性设置实例 基本介绍 关于消息队列的基本介绍,前面在学习system V的消息队列时已经有过了解,linux进程间通信:syst ...

  4. Linux进程间通信四 Posix 消息队列简介与示例

    目录 1. Posix 消息队列简介 2. API接口 2.1 创建或打开消息队列 2.2 发送消息 2.3 接收消息 2.4 获取.设置消息队列属性 2.5 关闭消息队列 2.6 删除消息队列 2. ...

  5. Linux下进程通信的八种方法

    Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...

  6. linux下的进程创建,Linux下进程的创建

    这篇文章主要是讲解到Linux进程的控制,包括程序和进程.守护进程.守护进程的出错处理. 1.程序和进程 程序(program)是存放在磁盘文件中的可执行文件,程序的执行实例被称为进程(process ...

  7. linux进程间通信:POSIX 消息队列 ----异步通信

    在上一篇中linux进程间通信:POSIX 消息队列我们知道消息队列中在消息个数达到了队列所能承载的上限,就会发生消息的写阻塞. 阻塞式的通信影响系统效率,进程之间在通信收到阻塞时并不能去做其他事情, ...

  8. linux看不到进程管理,关于Linux下进程的详解【进程查看与管理】

    关于Linux下进程的详解[进程查看与管理] 一.关于进程 进程: 已经启动的可执行程序的运行实力 进程的组成:一个进程包含内核中的一部分地址空间和一系列数据结构.其中地址空间是内核标记的一部分内存以 ...

  9. linux进程状态d状态,Linux下进程的状态

    如下信息来自于命令man ps Here are the different values that the s, stat and state output specifiers (header & ...

  10. Linux下进程隐藏的常见手法及侦测手段

    痕迹清理 1.  退出前 history -c 2.  多使用sftp吧 0.0 3.  web日志删除一些 4.  用户目录下很多 history,一言不合就是删 :) 4.  btmp wtmp ...

最新文章

  1. PC厂商如何演化移动互联网市场格局?
  2. android碎片按钮,Android 碎片(Fragment)
  3. boost源码剖析之:泛型函数指针类boost::function(rev#3)
  4. javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/
  5. Javascript中的关键字和保留字
  6. 互斥锁在python中的应用
  7. HTML5 file api读取文件的MD5码工具
  8. base64解密后乱码_血泪教训!记一个JavaMail 附件乱码的问题
  9. [转载] 【python系列】numpy中的tile函数
  10. 路由添加失败 参数错误_Django框架基础之路由详解 | 技术
  11. Hadoop安装与配置详细教程
  12. OpenCV 人脸识别、图片相似度检测
  13. 怎么可以修改pr基本图形中的文字_视频剪辑 | pr的简单教学
  14. c语言求范围内最大素数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
  15. python爬取小猪短租信息
  16. fork客户端mac使用教程
  17. 图片转字符画(python)
  18. 【课程】07 河口水循环
  19. python安装cpickle_python中cPickle
  20. C语言求满足条件的xyz,c++编程,已知有式子:xyz+yzz=532, 其中x、y、z为数字,编写程序输出所有满足条件的x、y和z。...

热门文章

  1. android horizontalscrollview顶部导航,带有居中效果的HorizontalScrollView使用说明
  2. Maven仓库的下载和配置settings.xml文件
  3. python在财务中的应用实训报告-数据科学与大数据技术专业实训解决方案
  4. 插件 阴阳师 百鬼夜行
  5. 易接SDK接入:Android手游支付功能接口实现,完整代码奉上
  6. 惯性导航算法(三)-方向余弦矩阵(下)
  7. 研旭至尊板——F28335知识点总结①
  8. 10个深度学习软件_关于深度学习的10个问题
  9. 高速接口SFP、GbE、SRIO、PCIE、CPRI和SGMII的参考时钟选择问题
  10. 判断一颗二叉树是否为二叉平衡树 python 代码