Linux进程间通信(System V) --- 消息队列
消息队列 IPC 原理
消息队列是消息的链式队列,如下图为消息队列的模型。整个消息队列有两种类型的数据结构。
1.msqid_ds 消息队列数据结构:描述整个消息队列的属性,主要包括整个消息队列的权限、拥有者、两个重要的指针(分别指向消息队列的第一个消息和最后一个消息)。
2.msg 消息队列数据结构:整个消息队列的主体,一个消息队列有若干个消息,每个消息数据结构的基本成员包括消息类型、消息大小、消息内容指针和下一个消息数据结构的位置。
消息队列还可以基于类型处理,但是,消息队列的 FIFO 原则仅仅适用于同类型的消息。在 Linux 中,对消息队列进行了以下规定(不同 Linux 版本的话值可能会不同):
1.默认情况下,整个系统最多允许有16个消息队列。
2.每个消息队列最大为16384字节。
3.消息队列中的每个消息最大为8192字节。
这些内容在 /usr/include/linux/msg.h 中进行定义:
#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
消息队列的基本属性
下图出于 /usr/include/linux/msg.h 文件
消息队列管理
1.创建消息队列:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/* 第一个参数为key值,一般由ftok()函数获得;第二个参数为访问权限 */
int msgget(key_t key, int msgflg);
2.消息队列属性控制
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/*
* 第一个参数为消息队列ID,由msgget获得
* 第二个参数为控制指令
* 第三个参数为数据传递的载体
*/
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
控制指令如下:
3.发送消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/*
* 第一个参数为消息队列ID
* 第二个参数 msgp 指向定义的缓冲区
* 第三个参数为发送消息的大小
* 第四个参数一般高为0,阻塞调用进程
*/
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
4.从消息队列接收消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/*
* 第一个参数为消息队列ID
* 第二个参数为临时消息数据结构,用于储存消息
* 第三个参数为接收消息的大小
* 第四个参数用于指定请求的消息类型
* 第五个参数一般设置为0,阻塞调用进程
*/
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
其中消息数据结构应定义如下:
/* From /usr/include/linux/msg.h */
struct msgbuf {
long mtype; /* 消息类型 */
char mtext[1]; /* 存储消息位置,需要重新定义 */
};
消息队列应用实例
创建两个进程,使用消息队列进行通信,一个进程发送消息,另一个进程接收消息。
发送端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf {
long mtype;
char mtext[50];
};
int main()
{
int key, msg_id;
static struct msgbuf buf;
key = ftok(".", 1);
msg_id = msgget(key, IPC_CREAT | 0600);
/* 设置消息的类型 */
buf.mtype = 1;
while(1){
fgets(buf.mtext, 50, stdin);
/* 输入quit退出进程,并删除队列 */
if(!strncmp(buf.mtext, "quit", 4)){
//msgctl(msg_id, IPC_RMID, 0);
exit(0);
}
/* 将消息发送到队列 */
msgsnd(msg_id, (void *)&buf, strlen(buf.mtext)+1, 0);
}
return 0;
}
接收端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype;
char mtext[50];
};
int main()
{
int key, msg_id;
static struct msgbuf buf;
key = ftok(".", 1);
msg_id = msgget(key, IPC_CREAT | 0600);
/* 设置消息类型 */
buf.mtype = 1;
while(1){
/* 从消息队列接收消息 */
msgrcv(msg_id, (void*)&buf, sizeof(buf), buf.mtype, 0);
printf("Recv msg : %s \n", buf.mtext);
}
return 0;
}
运行结果:
删除消息队列:
ipcrm -q msqid
Linux进程间通信(System V) --- 消息队列的更多相关文章
- 进程间通信 System V 消息队列
1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...
- Linux IPC System V 消息队列
模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> ftok() //获取key ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- linux c编程:System V消息队列一
消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进 ...
- linux网络编程之system v消息队列(二)
今天继续学习system v消息队列,主要是学习两个函数的使用,开始进入正题: 下面则开始用代码来使用一下该发送函数: 在运行之前,先查看一下1234消息队列是否已经创建: 用上次编写的查看消息队列状 ...
- 第6章 System V消息队列
6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...
- 利用System V消息队列实现回射客户/服务器
一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...
- UNIX环境高级编程——system V消息队列
unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消 ...
- Linux 进程间通信(posix消息队列 简单)实例
Linux 进程间通信(posix消息队列 简单)实例 详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm 编译: gcc -o consumer ...
随机推荐
- 【并发编程】IO模型
一.要点回顾 为了更好地了解IO模型,我们需要先回顾下几个概念:同步.异步.阻塞.非阻塞 同步: 一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行.就是在发出一个功能调用时,在没 ...
- Java集合:LinkedList源码解析
Java集合---LinkedList源码解析 一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...
- ActiveMQ_1学习
学习资源 官方文档 http://activemq.apache.org/features.html 下载ActiveMQ选择版本 http://activemq.apache.org/overvie ...
- springmvc 对日期的转换与处理
一,背景 近期项目上需求还没有确定,难道清闲,对项目中不合理的地方进行一些升级改造.鉴于项目使用的技术框架比较老旧(spring 3.0+) ,一直没有对此做大的升级改造.由于之前项目入参,出参都是使 ...
- php循环
while 例子: /* example 1 */ $a = 0; while (true) { $a++; echo $a.'<br>'; if($a >= 10){ break; ...
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记十四之铭文升级版
铭文一级: 第11章 Spark Streaming整合Flume&Kafka打造通用流处理基础 streaming.conf agent1.sources=avro-sourceagent1 ...
- so静态分析进阶练习——一个CreakeMe的分析思路
i春秋作家:HAI_ 原文来自:https://bbs.ichunqiu.com/thread-41371-1-1.html 说明 拿到一个CreakeMe,写一个分析思路.CreakMe主要是对.s ...
- Create-React-App项目外使用它的eslint配置
概述 使用Create-React-App脚手架感觉它的eslint配置有点好用,于是考虑不用Create-React-App脚手架该怎么使用这些配置. 我于是eject了Create-React-A ...
- MySQL的时间、日期型
MySQL的时间.日期型 MySQL中表示时间值的有DATE.时间类型为DATETIME.DATE.TIMESTAMP.TIME和YEAR.每个时间类型有一个有效值范围和一个"零" ...
- ubuntu 16.04 下更换boost版本
如果是新机器,没装过boost,那么直接一条命令 sudo apt-get install libboost-all-dev 头文件一般安装在 /usr/include 下面有一个目录boost,里面 ...