进程间通信——IPC机制(二)消息队列

2024-09-03 10:44

本文主要是介绍进程间通信——IPC机制(二)消息队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

 前言

一、什么是消息队列

二、创建消息队列的函数 


 前言

        在之前我的博客中讲述了传统的进程间通信方式,即通过管道传输,信号辅助;

        本文主要讲述消息的通信方式,即通过消息队列,和共享文件进行传输数据,后面也会使用信号灯、同步互斥机制来控制传输顺序。

一、什么是消息队列

        消息队列就是在内核中创建一个队列,进程会将数据打包成结点,添加到队尾,进程也可以从队头读取结点,实现进程的通信(先进先出的通信)

         消息队列的特点:

  • 消息队列的消息有固定的格式(消息的类型+消息的正文)
  • 消息队列根据先进先出原则读取数据,同时可以指定消息的类型进行读取

  • 消息队列独立于进程

  • 使用消息队列传输数据时,只有当两个进程都结束,消息队列才会被释放

二、创建消息队列的函数 

         1、msgget():创建消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgget(key_t key, int msgflg);
功能:通过key值,创建或打开一个key值对应的消息队列参数:
参数1:key_t key: key值
参数2:int msgflg:IPC_CREAT:如果key值对应的消息队列不存在,则创建消息队列IPC_CREAT | 0664 :创建的同时指定权限,如果消息队列已经存在,则会忽略这个权限返回值:
成功,返回消息队列的对应id     
失败,返回-1      

        2、msgsed():发送消息到消息队列中

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgsnd(int msqid, const void *msgp, size_t msgsz , int msgflg);
功能:向消息队列中发送消息参数:
参数1:int msqid:消息队列的id,指定进程要发送到哪个消息队列中
参数2:const void *msgp:指定要发送的消息的数据地址消息格式:----自定义struct msgbuf {long mtype;消息类型-------发送时,消息类型 > 0xxx mtext[xxx];消息的正文数据};
参数3:size_t msgsz:消息正文数据的大小, mtext大小
参数4:int msgflg:发送方式0:默认方式,当消息队列满了,msgsnd会阻塞等待IPC_NOWAIT:非阻塞方式,当消息队列满了,msgsnd 不会阻塞等待,直接结束当前函数,不发送返回值:
成功,返回0
失败,返回-1

        3、msgrcv():从指定的消息队列中读取数据

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
功能:从指定的消息队列中读取消息参数:
参数1:int msqid:要读取消息的消息队列id
参数2:void *msgp:指定要将读取的消息存储在哪个地址,注意,以什么类型写入消息队列,就以什么类型从消息队列中读取消息格式:----自定义struct msgbuf {long mtype;消息类型xxx mtext[xxx];消息的正文数据};        
参数3:size_t msgsz:消息正文大小,   mtext大小
参数4:long msgtyp:要读取的消息的类型msgtyp > 0 :读取消息队列中,指定  msgtyp 类型消息的第一条消息   msgtyp == 0  :读取消息队列中第一条消息
参数5:int msgflg:接收方式0:默认方式,当消息队列没有数据时,msgrcv会阻塞等待IPC_NOWAIT:非阻塞方式,当消息队列没有数据时,msgrcv 不会阻塞等待,直接结束当前函数,不接收返回值:成功,返回0失败,返回-1 

        

        4、msgctl():控制消息队列的函数,可以实现删除,获取队列信息等等的功能

     IPC_NOWAIT:非阻塞方式,当消息队列没有数据时,msgrcv 不会阻塞等待,直接结束当前函数,不接收返回值:成功,返回0失败,返回-1                                    4、msgctl
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:控制消息队列,主要用于删除消息队列参数:
参数1:int msqid:要控制操作的消息队列id
参数2:int cmd:控制命令IPC_STAT:获取消息队列属性,获取的属性值存储到 第三个参数 指针变量 对应的地址空间   IPC_SET:设置消息队列属性,把 第三个参数 指针变量对应空间的属性值 设置到消息队列中 IPC_RMID:删除消息队列, 第三个参数为 NULL返回值:
成功,返回0
失败,返回-1   

        例如,现在我要实现1.c和2.c之间的通信,如下:

1.c

//用消息队列实现两个进程之间的通信
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MSG_SIZE 80
//定义消息队列的结点
struct my_msg {long int type;char buf[MSG_SIZE];
};int main(void)
{int msgid;int ret;struct my_msg msg;//创建消息队列msgid = msgget((key_t)1235, 0666|IPC_CREAT);if (msgid == -1) {printf("msgget failed!\n");exit(1);//如果创建失败,结束进程}while(1){scanf("%ld",&(msg.type));	scanf("%s",msg.buf);// 传入0:如果消息队列满了,那么就阻塞ret = msgsnd(msgid, &msg, MSG_SIZE, 0);if (strcmp(msg.buf,"quit")==0) {printf("msgsnd failed!\n");break;}}//删除队列msgctl(msgid,IPC_RMID,NULL);return 0;
}

2.c

//接收消息队列的信息
#include<stdio.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<sys/msg.h>
struct my_msg
{long type;char buf[80];
};
int main(int argc, const char *argv[])
{//创建或者打开消息队列int msgid;msgid=msgget((key_t)1235,IPC_CREAT | 0664);if(msgid<0){perror("msgget failed:");return -1;}//从消息队列中读取数据while(1){struct my_msg my_data;int num;//输入队列下标获取对应数据scanf("%d",&num);//获取队列中的数据msgrcv(msgid,&my_data,sizeof(struct my_msg)-sizeof(long),num,0);printf("type=%ld,buf=%s \n",my_data.type,my_data.buf);if(strcmp(my_data.buf,"quit")==0){break;}}//关闭消息队列msgctl(msgid,IPC_RMID,NULL);return 0;
}

这篇关于进程间通信——IPC机制(二)消息队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1132747

相关文章

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Go语言中Recover机制的使用

《Go语言中Recover机制的使用》Go语言的recover机制通过defer函数捕获panic,实现异常恢复与程序稳定性,具有一定的参考价值,感兴趣的可以了解一下... 目录引言Recover 的基本概念基本代码示例简单的 Recover 示例嵌套函数中的 Recover项目场景中的应用Web 服务器中

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

Jvm sandbox mock机制的实践过程

《Jvmsandboxmock机制的实践过程》:本文主要介绍Jvmsandboxmock机制的实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景二、定义一个损坏的钟1、 Springboot工程中创建一个Clock类2、 添加一个Controller

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time