Linux进程间通信(IPC)-------消息队列
消息队列是进程间通信的一种方法,他有两个操作,一个进程来发送消息(也就是向内存中写入数据),另一个是获取消息(也就是另外一个进程在内存中读取数据)
下面来看消息队列的
创建,写入,读取等需要用到的函数
创建:msgget((key_t) key,int msgflg) 其中(key_t)key的话,我在管道,共享内存中都写过,key值没什么要求,大于零的32位整数就行,并且它是用来区分和别的消息队列的,所以key值别和其他消息队列重复就行
msgflg是个标志位,一般取IPC_CREAT :
如果消息队列对象不存在,则创建之,否则则进行打开操作;下面附上帮助手册
写入数据(发送消息):int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg )
其中参数msqid就是上述创建的消息队列的id
struct msgbuf *msgp这玩意就是结构体指针 该结构体就是消息体
msgsz就是消息体的大小
msgflg一般默认为0
读取数据(读取消息):size_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long type,int msgflg)
smqid就是创建的消息队列id
struct msgbuf *msgp 结构体指针
size_t msgsz 就是存消息的大小
long type 就是消息的类型
int msgflg标志位,一般默认0
下面附上帮助手册:
上述那个结构体struct msgbuf就是消息体,type用来区分消息,你发送或者获取消息的类型,其类型必须是long
下面的char 的数组就是发送或者获取消息的最大内存(这里有一点要提一下,就是上面说到msgsnd中消息体大小,只算这个结构体中的char数组,龙不计算在内)
下面来进行代码实现:发送端的编写
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是权限assert(msgid != -1);struct message me;me.type = 1; //这块将消息类型定义为1strcpy(me.buff,"hello"); //向buff中写入hellomsgsnd(msgid,(void*)&me,32,0); //向消息队列发送消息}
对获取端的编写:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是权限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,1,0); //消息存储最多32 1是type类型 0是默认标志位printf("read msg:%s \n",me.buff);}
下面附上运行截图(其中xiaoxi是发送消息,haha是获取消息) 那个已用字节数应该是32 因为xiaoxi这个发送端 我刚刚运行了下 ,所以叠加起来就是64
然后ipcs -q是查看消息队列的使用情况的,键下面的4d2就是1234转换为16进制的值
然后我们将发送消息的消息的类型值由1改为2,获取端代码不变,我们再来看一下结果
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是权限assert(msgid != -1);struct message me;me.type = 2; //这块将消息类型定义为1strcpy(me.buff,"hello"); //向buff中写入hellomsgsnd(msgid,(void*)&me,32,0); //向消息队列发送消息}
然后我们就会发现,获取端获取不了数据,一直在那块阻塞,因为类型不对,写入端写的是2类型,读取的是1类型
因为类型不对,写入端写的是2类型,读取的是1类型,所以肯定是读取不了的,那么有没有什么办法让它可以读取呢,最笨的办法就是将读取端的消息类型改为2,这也是最常规的办法,下面我来弄一个很有意思的方法:
将读取端msgrcv的消息类型改为0,也就是默认类型,这样的话,它就会接受所有的数据类型,下面我们来试一下:只改获取端,发送端代码不该,还是2类型
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是权限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,0,0); //消息存储最多32 1是type类型 0是默认标志位printf("read msg:%s \n",me.buff);}
附上运行截图:
然后删除消息队列msgctl(msgid,IPC_RMID,NULL)
将该代码写到获取端的末尾就好!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是权限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,0,0); //消息存储最多32 1是type类型 0是默认标志位printf("read msg:%s \n",me.buff);if(msgctl(msgid,IPC_RMID,NULL) == -1) //这块msgctl中的那个NULL参数还没搞明白 下次课过去问一下老师在评论区补一下{printf("delete error");}}
这样执行下来就可以在程序执行完成之后,删除消息队列!
“加油呀 兄弟们 BAT 我来了”
Linux进程间通信(IPC)-------消息队列相关推荐
- c语言系统编程八:Linux进程间通信之消息队列
Linux进程间通信之消息队列 一 消息队列概述 二 消息队列的特点 三 消息队列的创建和使用 3.1 获取系统唯一的key值 3.2 创建消息队列 3.3 查看消息队列和删除消息队列的shell命令 ...
- Linux进程间通信——使用消息队列
下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了 ...
- linux 进程uhxuhao,linux 进程间通信三 消息队列以及实例
转自 http://blog.csdn.net/liang890319/article/details/8280934 代码来自:嵌入式Linux应用开发标准教程 消息可以理解为写信给某个人,这里在应 ...
- linux进程间通信:消息队列实现双端通信
双端通信描述 利用消息队列针对发送接受消息的类型唯一性 进行多个客户端之间消息传递,而不需要server端进行消息转发. 同时消息队列的读阻塞和写阻塞特性(消息队列中已经写入数据,如果再不读出来,则无 ...
- linux 消息对lie_Linux进程间通信之消息队列总结
一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符( i d ...
- linux消息通信无法接收,进程间通信:消息队列有关问题:进程1接收不到进程2的消息...
进程间通信:消息队列有关问题:进程1接收不到进程2的消息 进程间通信:消息队列有关问题:进程1接收不到进程2的消息 日期:2014-05-16 浏览次数:20365 次 进程间通信:消息队列问题:进程 ...
- 进程间通信之消息队列
一.什么是消息队列 unix早期通信机制之一的信号能够传送的信息量有限,管道则只能传送无格式的字节流,这无疑会给应用程序开发带来不便.消息队列(也叫做报文队列)则克服了这些缺点. 消息队列就是一个消息 ...
- Linux系统中消息队列,共享内存、信号和线程的基本操作使用方法
Linux系统中消息队列,共享内存.信号和线程高级操作 第十一章 消息队列 10.1消息队列定义 10.2 消息队列特点 10.3 key值 10.4 创建消息队列 10.4.1 发送消息 10.4. ...
- linux软中断和消息队列结合,传统UNIX进程间通信内核实现概要
1概述 大型的应用系统,有两种方式可以建立: 1.通过一个孤立的.大型的.复杂的进程实现全部功能:如见日益复杂,规模庞大,该方法已不现实 2.通过若干相互联系的.小型的.相对简单的进程构成的组合来提供 ...
最新文章
- 如何用Python批量提取PDF文本内容?
- 程序猿职业规划,未来该何去何从
- r语言工作路径linux,R语言实用基础知识_工作路径-注释-安装和卸载R包_2019-12-01...
- 华为笔记本matebook13_华为MateBook 13_HUAWEI MateBook 13(i5 8265U/8GB/256GB/独显)_笔记本导购-中关村在线...
- 《收集苹果》 动态规划入门
- 【转】使用JDK自带jvisualvm监控tomcat
- MySQL 之 索引
- C++中使用set和unordered_set的find方法时遇到的小坑
- AI人工智能技术可以做什么
- 生物医学数据统计分析-回归分析
- 避免安信可导入SDK出错
- Selenium中的鼠标单击事件
- javajavaScript常见校验器
- 行人跟踪之身份识别(三)
- 使用阿里云服务器搭建代理服务器
- 【python】python matplotlib绘制并保存多张图片+绘制多张子图
- “.CHM文件”无法打开
- Word计算机与网络应用原题,计算机应用基础考试试题附答案
- 第一代计算机磁鼓,磁鼓计算机
- python 挂起_Python Killing挂起函数