【详解】进程间通信之消息队列

消息队列:

操作系统在内核中创建一个队列,使得用户进程可以一个放数据,一个取数据,消息队列中的每个节点存放的信息有:消息类型号、消息的长度、消息的具体内容,具体情况如图:

所引用的头文件:

#include<sys.msg.h>

#include<sys/ipc.h>

打开或者创建一个消息队列:

msgget(key_t key,int flags)

内核对象没有文件名这一说,它用key来代表,用flags来赋予权限  

flags:IPC_CREAT|0644 :创建并赋予权限

           打开用0就可以

返回值为消息队列的id,相当于open打开文件的文件描述符。

具体代码:

  1 #include<sys/ipc.h>
  2 #include<stdio.h>
  3 #include<sys/msg.h>
  4 #include<stdlib.h>
  5 
  6 int main()
  7 {
  8    int msgid= msgget(12,IPC_CREAT|0644);
  9    if(msgid==-1)
 10    {
 11        perror("msgget");
 12        exit(1);
 13    }
 14    else
 15    {
 16        printf("msg creat success");                                         
 17    }
 18 
 19 }

往消息队列中放数据:

msgsnd(int  id,const void *msgp,size_t len,int flag)

id为msgget的返回值,即已打开的消息队列

msgp所要发送消息的位置

len:消息的字节数,不包括channel的大小

flag:0   达到上限等待取走后再放入

失败返回-1,成功返回0

struct msgbuf{

       long channel; //消息类型,必须>=1

       char mtext[ ];//写上自己消息的内容。

       };

atoi 把字符串转化成整形数

具体代码:

  1 #include<stdio.h>                                                           
  2 #include<string.h>
  3 #include<sys/msg.h>
  4 #include<sys/ipc.h>
  5 #include<stdlib.h>
  6 struct msgbuf{
  7     long mtype;
  8     char mtext[100];
  9 };
 10 int main(int argc,char *argv[])
 11 {
 12     if(argc!=2)
 13     {
 14         fprintf(stderr,"usage:%s type\n",argv[0]);
 15         exit(1);
 16     }
 17     int id=msgget(12,0);
 18     if(id==-1)
 19     {
 20         perror("msgget");
 21         exit(1);
 22     }
 23     struct msgbuf mb;
 24     memset(&mb,0x00,sizeof(mb));
 25     mb.mtype=atoi(argv[1]);
 26     printf("msg:");
 27     fgets(mb.mtext,99,stdin);
 28     int r=msgsnd(id,&mb,strlen(mb.mtext),0);
 29     if(r==-1)
 30     {
 31         perror("msgsnd");
 32         exit(1);
 33     }
 34 }              

从消息队列取数据

msgrcv(int id,const void *msgp,size_t len,long msgtype,int flag)

调用一次获取一个数据,如果类型号相同,则取第一个入队的数据

id:已打开的消息队列

msgp:消息存放的位置

len:不包括消息类型的大小,只是装数据的大小

msgtype:获取消息类型为几的参数

flag:0

失败返回-1,成功返回实际读取的字节数

具体代码:

 1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>                                                          
  4 #include<sys/msg.h>
  5 #include<sys/ipc.h>
  6 struct msgbuf{
  7     long mtype;
  8     char mtext[100];
  9 };
 10 int main(int argc,char* argv[])
 11 {
 12     if(argc!=2)
 13     {
 14         fprintf(stderr,"usage:%s type\n",argv[0]);
 15         exit(1);
 16     }
 17     int id=msgget(12,0);
 18     if(id==-1)
 19     {
 20         perror("msgget");
 21         exit(1);
 22     }
 23     struct msgbuf mb;
 24     memset(&mb,0x00,sizeof(mb));
 25     if(msgrcv(id,&mb,100,atoi(argv[1]),0)==-1)
 26     {
 27         perror("msgrcv");
 28         exit(1);
 29     }
 30     printf("msg:%s\n",mb.mtext);
 31 }                                 

销毁消息队列:

int msgctl(int  id, int cmd, struct msqid_ds *buf);

id:已打开的消息队列

cmd:命令,我们通常选用IPC_RMID 关闭消息队列

buf:NULL

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/ipc.h>
  4 #include<sys/msg.h>
  5 int main()
  6 {
  7     int id=msgget(12,0);
  8     msgctl(id,IPC_RMID,NULL);                                               
  9 }

补充说明:

用ipcs可以查看ipc对象(共享内存、消息队列、信号量全部都会显示出来)

ipcs -q 只查看消息队列

ipcrm -Q key 删除指定IPC对象的消息队列

这里我们以创建、删除为例示范:

系统中最多可以创建多少个消息队列?

用cat/proc/sys/kernel/msgmni可以查看

一条消息最多能装多少个字节?

cat/proc/sys/kernel/msgmax

一个消息队列中所有消息的总字节数为多少?

cat/proc/sys/kernel/msgnb

 

版权声明:本文为enjoymyselflzz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/enjoymyselflzz/article/details/81569044

智能推荐

【c++】模板和模板类

C++是一种“强类型”语言。也就是说,对于一个变量,编译器必须确切知道它是什么类型。但是,这种强类型函数在实现一些简单函数反而更麻烦。例如:求两大数的较大者,应以Max( )函数,我们需要对不同数据类型分别定义不同重载版本来实现: 我们看到,虽然我们可以通过函数重载去实现,但明显存在一些缺点: 1、所有的函数除返回类型外,函数体都相同,代码复用率低; 2、只要新类型出现,我...

[java][事务]tcc事务实战学习过程

学习项目:https://github.com/14251104246/spring-cloud-rest-tcc 下载源码,进入源码目录运行:mvn clean package Docker Compose运行 docker-compose -f infrastructure-compose.yml up -d docker-compose -f basic-ms-compose.yml up ...

[学习记录,]Mybatis入门

环境: Eclipse 2019 Tomcat 9.0 jdk1.8 开搞 首先创建工程 结构如下 导入Jar包 可在mybatis官网下载 http://www.mybatis.cn/82.html 配置文件mybatis-config.xml 事务管理有两种:JDBC和MANAGED JDBC: MANAGED 数据源类型:UNPOOLED、POOLED、JNDI 创建实体类文件User.ja...

运用for语句来判断数组中值得大小

总结: 1将if语句与数组联合起来判断输入中各组中的最大最小值; 2注意:定义的数组数量是躲多少就要输入多少组数据,少输入就无法输出;...

Bridging signals

Bridging signals Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 10926Accepted: 5982 Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once ...

猜你喜欢

一天一大 leet

一天一大 leet 题目(难度:困难): 示例 抛砖引玉 官方答案 高手在民间 菜鸡的自白 20200606 题目(难度:困难): 给定一个未排序的整数数组,找出最长连续序列的长度。 要求算法的时间复杂度为 O(n)。 示例 示例 抛砖引玉 要求算法的时间复杂度为 O(n),即限制了只能循环一次; 先对数组排序 循环数组记录后一个元素等于前一个元素+1或者等于前一个元素的数量 满足条件++,不然重...

Tensorflow实现的CNN文本分类

https://blog.csdn.net/somtian/article/details/69359498 原博文, github 在这篇文章中,我们将实现一个类似于Kim Yoon的卷积神经网络语句分类的模型。 本文提出的模型在一系列文本分类任务(如情感分析)中实现了良好的分类性能,并已成为新的文本分类架构的标准基准。 本文假设你已经熟悉了应用于NLP的卷积神经网络的基础知识。 如果没有,建议...

JDBC新手入门教程

开发工具:idea 数据库:mysql jar包:junit-4.10 mysql-connector-java-8.0.18 junit-4.10下载 mysql-connector-java-8.0.18下载 注意1:jdbc的驱动因为使用的是mysql-connector-java-8.0.18,所以为(“com.mysql.cj.jdbc.Driver”),而不是(...

Lua 排序 table.sort

    正如C#中有Array.Sort(),lua中也有自己的排序方法即table.sort(table,function)。     lua中的排序默认是从大到小的排序;     传入一个方法参数,可以使排序从小到大; 打印结果:  ...

SURF算法简述及Python标记SURF特征检测实践

目录 一、SURF算法 1.算法简介 2.SURF与SIFT的具体差异 二、Python代码实践 1.测试环境 2.测试代码 3.核心函数 4.测试结果 一、SURF算法 1.算法简介 SURF(Speeded-Up Robust Features)加速稳健特征,是一种稳健的局部特征点检测和描述算法。 SURF是对SIFT算法的改进,该算子在保持 SIFT 算子优良性能特点的基础上,同时解决了 S...