消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这种系统IPC对象使用的控制方法和文件系统非常类似。使用对象的引用标志符作为资源表中的索引。

消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。

Linux采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。这种通信机制相对简单,但是应用程序使用起来就需要使用相对复杂的方式来应付了。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。

消息队列是kernel persistence并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构 (struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中中找到访问入口。

IPC标识符:每一个I P C目标都有一个唯一的I P C标识符。这里所指的I P C目标是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 I P C目标。

IPC 关键字:想要获得唯一的标识符,则必须使用一个 I P C关键字。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一步。在System V IPC机制中,建立两端联系的路由方法是和I P C关键字直接相关的。通过在应用程序中设置关键字值,每一次使用的关键字都可以是相同的。一般情况下,可以使用f t o k ( )函数为客户端和服务器端产生关键字值。

二、ipcs 命令

命令ipcs用于读取System V IPC目标的状态。
ipcs -q: 只显示消息队列。
ipcs -s: 只显示信号量。
ipcs -m: 只显示共享内存。
ipcs –help: 其他的参数。

下面是ipcs命令输出的例子:

[root@wanglong wanglong]# ipcs

—— Shared Memory Segments ——–

key        shmid      owner      perms      bytes      nattch     status

0×00000000 0          root      644        40         2

0×00000000 32769      root      644        16384      2

0×00000000 65538      root      644        268        2

—— Semaphore Arrays ——–

key        semid      owner      perms      nsems

0×000000a7 0          root      600        1

0×00000000 98305      apache    600        1

0×00000000 65538      apache    600        1

0×00000000 131075     apache    600        1

0×00000000 163844     apache    600        1

0×00000000 196613     apache    600        1

0×00000000 229382     apache    600        1

0×00000000 262151     apache    600        1

0×00000000 294920     apache    600        1

—— Message Queues ——–

key        msqid      owner      perms      used-bytes   messages

三、消息队列的主要调用

内核中实现消息传递机制的代码基本上都在文件ipc/msg.c中,消息队列的主要调用有下面4个,这里只作简单介绍:

(1)msgget:调用者提供一个消息队列的键标 (用于表示个消息队列的唯一名字),当这个消息队列存在的时候, 这个消息调用负责返回这个队列的标识号;如果这个队列不存在,就创建一个消息队列,然后返回这个消息队列的标识号 ,主要由sys_msgget执行。

(2)msgsnd:向一个消息队列发送一个消息,主要由sys_msgsnd执行。

(3)msgrcv:从一个消息队列中收到一个消息,主要由sys_msgrcv执行。

(4)msgctl:在消息队列上执行指定的操作。根据参数的不同和权限的不同,可以执行检索、删除等的操作,主要由sys_msgctl执行。

四、消息队列的应用例子

下面的例子很好的演示了创建、发送、读取、改变权限以及删除消息队列各种操作:

消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这种系统IPC对象使用的控制方法和文件系统非常类似。使用对象的引用标志符作为资源表中的索引。
消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。
Linux采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。这种通信机制相对简单,但是应用程序使用起来就需要使用相对复杂的方式来应付了。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。
消息队列是随内核持续的并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构 (struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中中找到访问入口。
IPC标识符:每一个I P C目标都有一个唯一的I P C标识符。这里所指的I P C目标是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 I P C目标。
IPC 关键字:想要获得唯一的标识符,则必须使用一个 I P C关键字。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一步。在System V IPC机制中,建立两端联系的路由方法是和I P C关键字直接相关的。通过在应用程序中设置关键字值,每一次使用的关键字都可以是相同的。一般情况下,可以使用f t o k ( )函数为客户端和服务器端产生关键字值。
二、ipcs 命令
命令ipcs用于读取System V IPC目标的状态。
ipcs -q: 只显示消息队列。
ipcs -s: 只显示信号量。
ipcs -m: 只显示共享内存。
ipcs –help: 其他的参数。
下面是ipcs命令输出的例子:
[root@wanglong wanglong]# ipcs
—— Shared Memory Segments ——–
key        shmid      owner      perms      bytes      nattch     status
0×00000000 0          root      644        40         2
0×00000000 32769      root      644        16384      2
0×00000000 65538      root      644        268        2
—— Semaphore Arrays ——–
key        semid      owner      perms      nsems
0×000000a7 0          root      600        1
0×00000000 98305      apache    600        1
0×00000000 65538      apache    600        1
0×00000000 131075     apache    600        1
0×00000000 163844     apache    600        1
0×00000000 196613     apache    600        1
0×00000000 229382     apache    600        1
0×00000000 262151     apache    600        1
0×00000000 294920     apache    600        1
—— Message Queues ——–
key        msqid      owner      perms      used-bytes   messages
三、消息队列的主要调用
内核中实现消息传递机制的代码基本上都在文件ipc/msg.c中,消息队列的主要调用有下面4个,这里只作简单介绍:
(1)msgget:调用者提供一个消息队列的键标 (用于表示个消息队列的唯一名字),当这个消息队列存在的时候, 这个消息调用负责返回这个队列的标识号;如果这个队列不存在,就创建一个消息队列,然后返回这个消息队列的标识号 ,主要由sys_msgget执行。
(2)msgsnd:向一个消息队列发送一个消息,主要由sys_msgsnd执行。
(3)msgrcv:从一个消息队列中收到一个消息,主要由sys_msgrcv执行。
(4)msgctl:在消息队列上执行指定的操作。根据参数的不同和权限的不同,可以执行检索、删除等的操作,主要由sys_msgctl执行。
四、消息队列的应用例子
下面的例子很好的演示了创建、发送、读取、改变权限以及删除消息队列各种操作:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_SEND_SIZE 80
struct mymsgbuf {
long mtype;
char mtext[MAX_SEND_SIZE];
};
void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text);
void read_message(int qid, struct mymsgbuf *qbuf, long type);
void remove_queue(int qid);
void change_queue_mode(int qid, char *mode);
void usage(void);
int main(int argc, char *argv[])
{
key_t key;
int msgqueue_id;
struct mymsgbuf qbuf;
if(argc == 1)
usage();
/* Create unique key via call to ftok() */
key = ftok(“.”, ’m');
/* Open the queue - create if necessary */
if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1)
{
perror(“msgget”);
exit(1);
}
switch(tolower(argv[1][0]))
{
case ’s’: send_message(msgqueue_id, (struct mymsgbuf *)&qbuf,atol(argv[2]), argv[3]);
break;
case ’r': read_message(msgqueue_id, &qbuf, atol(argv[2]));
break;
case ’d': remove_queue(msgqueue_id);
break;
case ’m': change_queue_mode(msgqueue_id, argv[2]);
break;
default: usage();
}
return(0);
}
void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text)
{
/* Send a message to the queue */
printf(“Sending a message …n”);
qbuf->mtype = type;
strcpy(qbuf->mtext, text);
if((msgsnd(qid, (struct msgbuf *)qbuf,
strlen(qbuf->mtext)+1, 0)) ==-1)
{
perror(“msgsnd”);
exit(1);
}
}
void read_message(int qid, struct mymsgbuf *qbuf, long type)
{
/* Read a message from the queue */
printf(“Reading a message …n”);
qbuf->mtype = type;
msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0);
printf(“Type: %ld Text: %sn”, qbuf->mtype, qbuf->mtext);
}
void remove_queue(int qid)
{
/* Remove the queue */
msgctl(qid, IPC_RMID, 0);
}
void change_queue_mode(int qid, char *mode)
{
struct msqid_ds myqueue_ds;
/* Get current info */
msgctl(qid, IPC_STAT, &myqueue_ds);
/* Convert and load the mode */
sscanf(mode, ”%ho”, &myqueue_ds.msg_perm.mode);
/* Update the mode */
msgctl(qid, IPC_SET, &myqueue_ds);
}
void usage(void)
{
fprintf(stderr, ”msgtool - A utility for tinkering with msg queuesn”);
fprintf(stderr, ”nUSAGE: msgtool (s)end n”);
fprintf(stderr, ” (r)ecv n”);
fprintf(stderr, ” (d)eleten”);
fprintf(stderr, ” (m)ode n”);
exit(1);
}
程序保存为 ipcs.c
编译:gcc -o ipcs ipcs.c
程序运行结果解释:
[root@wanglong wanglong]# ./ipcs  s  001  hello!
Sending a message …
[root@wanglong wanglong]# ./ipcs  s  001  world!
Sending a message …
[root@wanglong wanglong]# ./ipcs  s  001  you
Sending a message …
[root@wanglong wanglong]# ./ipcs  s  001  and
Sending a message …
[root@wanglong wanglong]# ./ipcs  s  001  me!
Sending a message …
[root@wanglong wanglong]# ./ipcs  r  001
Reading a message …
Type: 001 Text:hello!
[root@wanglong wanglong]# ./ipcs  r  001
Reading a message …
Type: 001 Text:world!
[root@wanglong wanglong]# ./ipcs  r  001
Reading a message …
Type: 001 Text:you
[root@wanglong wanglong]# ./ipcs  d  001    /*删除了消息队列001*/
[root@wanglong wanglong]# ./ipcs  r  001
Reading a message ..                        ./* 因为删除了,所以读不出消息了*/

程序保存为 ipcsvmsg.c

编译:gcc -o ipcsvmsg ipcsvmsg.c

程序运行结果解释:

Linux消息队列原理与应用相关推荐

  1. linux 消息队列 msgget/msgsnd/msgrecv

    专栏内容:linux下并发编程 个人主页:我的主页 座右铭:天行健,君子以自强不息:地势坤,君子以厚德载物. 目录 前言 概述 原理 消息队列的大小 查看资源 接口 代码演示 结尾 前言 本专栏主要分 ...

  2. linux消息队列非亲缘,linux进程

    linux进程Tag内容描述: 1.linux消息队列进程通信 一.消息队列的基本概念消息队列(也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一.另外两种是信号灯和共享内存.这些IPC机制 ...

  3. linux.调整收发队列,linux消息队列通信

    程序目的:学习linux消息队列通信 所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl() 首先介绍每个函数的用法: (1)msgget 使用格式: #include ...

  4. 基于 Kafka 和 ZooKeeper 的分布式消息队列原理

    转载:https://gitbook.cn/books/5bc446269a9adf54c7ccb8bc/index.html 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量 ...

  5. 再谈基于 Kafka 和 ZooKeeper 的分布式消息队列原理

    关于分布式消息队列,我在几个月前写过一篇文章:<深入浅出理解基于 Kafka 和 ZooKeeper 的分布式消息队列 >.最近,由于写作课程<分布式中间件实践之路>的契机,我 ...

  6. Kafka(消息队列原理,kafka定义,Kafka架构原理,kafka架构的工作流程)秒懂的kafka

    目录 什么是Kafka? 消息队列原理: 为什么要用Kafka? kafka的架构 kafka工作流程详解: 什么是Kafka? kafka是一个分布式消息队列 这个定义意味深长,记住容易,理解不易. ...

  7. linux 消息队列机制

    现在我们来讨论第三种也是最后一种System V IPV工具:消息队列.在许多方面看来,消息队列类似于有名管道,但是却没有与打开与关闭管道的复杂关联.然而,使用消息队列并没有解决我们使用有名管道所遇到 ...

  8. linux消息队列总结

    1.消息队列简介 实现linux进程通信的方式有5种: --信号(Singal) --管道(Pipe) --消息队列(Message) --信号量(Semaphore) 每种进程通信方式实现方式和功能 ...

  9. php 阻塞消息队列,linux 消息队列阻塞

    php 使用socket告知Python,可以在socket上声明是及时推送还是延迟推送######哦?愿闻其详 那要是很多用户同时并发呢######system 调用外部程序是一种办法######@ ...

最新文章

  1. c语言getchar的不赋任何变量,C语言中getchar中的问题
  2. 应对百度算法调整的三大优化技巧
  3. pkcs#11和Cryptoki的介绍
  4. java重入锁,再探JAVA重入锁
  5. 快手 算法工程师 0825 笔试题
  6. 使用OWC 做图表时按周、月、年设置时间刻度是参数无效问题解决方法
  7. 通过js动态设置select中option选中
  8. 数据可视化历史上的“人肉里程碑”
  9. AD19---彻底解决原理图转PCB时,出现failed to add class member及Unknown Pin的问题
  10. 宗地图绘制要求和规范_国内土地市场宗地图的绘制标准制图规范-【领仕网】...
  11. 面包板电源线怎么接_电路实验中,直接用面包板连接线将电源短路会产生什么问题?...
  12. 爬取虎嗅 5 万篇文章告诉你怎么样取标题
  13. win10家庭中文版切换语言
  14. Hotpot - 让使用CKettle像吃火锅一样爽
  15. WindowsServer2012R2 SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)解决办法
  16. 基片集成波导天线设计基础
  17. 目标检测之CSK(Exploiting the Circulant Structure of Tracking-by-detection with Kernels)
  18. 红米k30支持html,红米K30S至尊纪念版发布:骁龙865+支持144Hz高刷
  19. gltf 2.0快速入门
  20. 冬天OS(二十六):完善硬盘的驱动程序

热门文章

  1. java环境搭建及概述
  2. 游戏特效贴图的制作与应用
  3. 数据中心电气施工工序工艺管理要点
  4. 1349:最优布线问题
  5. Win11蓝牙开关没了如何修复?
  6. MyBatis(用于简化JDBC开发)
  7. 说说jdk和jre的区别和联系?
  8. Ps学习(多边形套索工具使用)
  9. linux解压war包后删除war包,解压好的文件夹跟着消失
  10. pta判断上三角矩阵