一、什么是消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。

消息队列的最佳定义是:内核地址空间中的内部链表。消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取。当然,每个消息队列都是由 IPC标识符所唯一标识的。

二、消息队列的创建

#include <sys/types.h>
   #include <sys/ipc.h>
   #include <sys/msg.h>
   int msgget(key_t key, int msgflg)

key:键值,由ftok获得。
   msgflg:标志位。

IPC_CREAT—如果在内核中不存在该队列,则创建它。

IPC_EXCL—当与IPC_CREAT一起使用时,如果队列早已存在则将出错。

返回值:与健值key相对应的消息队列描述字

三、读写消息队列

include <sys/msg.h>

int msgsnd ( int msqid, const void *prt, size_t nbytes, int flags);

对于写入队列的每一个消息,都含有三个值,正长整型的类型字段、数据长度字段和实际数据字节。新的消息总是放在队列的尾部,函数中参数msqid指定要操作的队列,ptr指针指向一个msgbuf的结构,定义如下:

struct msgbuf{

long mtype;

char mbuf[];

};

这是一个模板的消息结构,其中成员 mbuf是一个字符数组,长度是根据具体的消息来决定的,切忌消息不能以NULL结尾。成员mtype是消息的类型字段。

函数参数nbytes指定了消息的长度,参数flags指明函数的行为。函数成功返回0,失败返回–1并设置错误变量errno。errno可能出现的值有:EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL和ENOMEM。当函数成功返回后会更新相应队列的msqid_ds结构。

使用函数msgrcv可以从队列中读取消息,函数原型如下:

#include <sys/msg.h>

ssize_t msgrcv ( int msqid, void *ptr, size_t nbytes, long type , int flag);

函数中参数msqid为指定要读的队列,参数ptr为要接收数据的缓冲区,nbytes为要接收数据的长度,当队列中满足条件的消息长度大于nbytes的值时,则会参照行为参数flag的值决定如何操作:当flag中设置了MSG_NOERROR位时,则将消息截短到nbytes指定的长度后返回。如没有MSG_NOERROR位,则函数出错返回,并设置错误变量errno。设置type参数指定msgrcv函数所要读取的消息,tyre的取值及相应操作如表所示。

type值详解

等于0

返回队列最上面的消息(根据先进先出规则)

       

大于0

返回消息类型与type相等的第1条消息

       

小于0

返回消息类型小于等于type绝对值的最小值的第1条消息

       

参数flag定义函数的行为,如设置了IPC_NOWAIT位,则当队列中无符合条件的消息时,函数出错返回,errno的值为ENOMSG。如没有设置IPC_NOWAIT位,则进程阻塞直到出现满足条件的消息出现为止,然后函数读取消息返回。

下面实例演示了消息队列在进程间的通信。程序中创建了一个消息的模板结构体,并对声明变量做初始化。使用 msgget 函数创建了一个消息队列,使用 msgsnd 函数向该队列中发送了一条消息。

四、消息队列的控制

该函数用来控制消息队列,它与共享内存的shmctl函数相似,它的原型为:

int msgctl(int msgid, int command, struct msgid_ds *buf); 

ommand是将要采取的动作,它可以取3个值,

IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
IPC_RMID:删除消息队列

五、实例

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct my_msg_st
{long int my_msg_type;char some_text[BUFSIZ];
};int main(void)
{int running=1;int msgid;struct my_msg_st some_data;long int msg_to_receive=0;/*创建消息队列*/msgid=msgget((key_t)1234,0666 | IPC_CREAT);if(msgid==-1){fprintf(stderr,"msgget failed with error: %d\n",errno);exit(EXIT_FAILURE);}/*循环从消息队列中接收消息*/while(running){/*读取消息*/if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1){fprintf(stderr,"msgrcv failed with error: %d\n",errno);exit(EXIT_FAILURE);}printf("You wrote: %s",some_data.some_text);/*接收到的消息为“end”时结束循环*/if(strncmp(some_data.some_text,"end",3)==0){running=0;}}/*从系统内核中移走消息队列*/if(msgctl(msgid,IPC_RMID,0)==-1){fprintf(stderr,"msgctl(IPC_RMID) failed\n");exit(EXIT_FAILURE);}exit(EXIT_SUCCESS);
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_TEXT 512struct my_msg_st
{long int my_msg_type;char some_text[MAX_TEXT];
};int main(void)
{int running=1;struct my_msg_st some_data;int msgid;char buffer[BUFSIZ];/*创建消息队列*/msgid=msgget((key_t)1234,0666 | IPC_CREAT);if(msgid==-1){fprintf(stderr,"msgget failed with error:%d\n",errno);exit(EXIT_FAILURE);}/*循环向消息队列中添加消息*/while(running){printf("Enter some text:");fgets(buffer,BUFSIZ,stdin);some_data.my_msg_type=1;strcpy(some_data.some_text,buffer);/*添加消息*/if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,0)==-1){fprintf(stderr,"msgsed failed\n");exit(EXIT_FAILURE);}/*用户输入的为“end”时结束循环*/if(strncmp(buffer,"end",3)==0){running=0;}}exit(EXIT_SUCCESS);
}

linux 消息队列实现通信相关推荐

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

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

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

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

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

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

  4. 18 freertos消息队列-任务通信

    十八:18 freertos消息队列-任务通信 试验源码: #include <stdio.h> #include "board.h" #include "l ...

  5. linux 消息队列的单工通信,半双工通信

    目录 一 回顾 二 消息队列的单工通信 三 消息队列的半双工通信 一 回顾 1 通过 fgets函数实现输入指令 2 再通过 msgnsd 函数读取 值 3 最后通过 msgrcv函数获取 值 输出 ...

  6. PHP下操作Linux消息队列完成进程间通信的方法

    2019独角兽企业重金招聘Python工程师标准>>> 来源:http://www.jb51.net/article/24353.htm 关于Linux系统进程通信的概念及实现可查看 ...

  7. [Linux]消息队列

    我们知道进程间通信的方法有多种,主要有管道,消息队列,信号量,共享内存,socket等.之前介绍过管道,今天再介绍一个新的概念–消息队列. 消息队列:将一个进程到另一个进程之间发送数据块的方式.这些发 ...

  8. linux消息队列总结

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

  9. linux 消息队列_Linux消息队列

    消息队列,Unix的通信机制之一,可以理解为是一个存放消息(数据)容器.将消息写入消息队列,然后再从消息队列中取消息,一般来说是先进先出的顺序.可以解决两个进程的读写速度不同(处理数据速度不同),系统 ...

  10. Linux消息队列原理与应用

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

最新文章

  1. 电视信号——行场同步
  2. python实现tcp通信_Python实现简易TCP通信程序
  3. Sources for NFC/RFID inspection ( Soft Materials )
  4. php ci oracle,CI连接Oracle 11G数据库
  5. 2017年9月分c语言,2020年9月中国编程语言排行榜
  6. 04-并发编程-CountDownLatch、CyclicBarrier和 Semaphore
  7. (篇七)输入任意个数字,输出最大值最小值,且进行排序排序
  8. 3风扇声音怎么调小_美的风扇价格表
  9. 如何将论文中的公式图片直接变为word中的公式
  10. python坐标轴的粗细设置
  11. 使用 SAP UI5 Smart Chart 控件轻松绘制十数种不同类型的专业图表试读版
  12. 电子邮件附件下载器简介
  13. 设备配网专题《原理分析,设备配网技术之AP配网》
  14. 面试测试岗想拿13K,HR说你最多值10K,教你怼死HR?
  15. 魔力宝贝服务器修改技能经验,【石器时代】 GM添加、命令使用、经验及倍数设置、宠添加、查找及修改【附图】...
  16. 阿里巴巴起诉迪拜“阿里巴巴币”商标侵权:别让人误以为阿里在发币
  17. Python+Vue计算机毕业设计基于微服务的闪聚支付系统设计vwt4i(源码+程序+LW+部署)
  18. 重磅!机器人杀手真来了?韩国研究AI武器 遭多国抵制
  19. 计算机音乐制作专业大纲,电脑音乐制作教学大纲1.doc
  20. Python项目——飞机大战!

热门文章

  1. ppt五种经典字体组合
  2. PDF如何添加下划线 捷速PDF编辑器一键搞定
  3. 冥思苦想,木疙瘩也能崩出个豆:扯一下各大软件的用户体验
  4. 微博视频php解析,微博视频的地址解析下载
  5. Python xlwt 操作 excel 表格基础(一):单元格写入、合并、插入位图等
  6. [常用工具] Python视频处理库VidGear使用指北
  7. matlab风应力工具包,MSATSI:结合可靠经典方法的新简化用户处理及可视化工具的应力反演MATLAB软件包.pdf...
  8. 2021几款好用的思维导图软件推荐!
  9. java解析json对象_JAVA解析JSON数据
  10. PlaySound的同步播放与异步播放