首页 > 系统相关 >进程间通信之消息队列详解

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

时间:2024-09-10 17:52:28浏览次数:13  
标签:队列 msgid 间通信 详解 消息 key message include

目录

一、什么是消息队列?

二、消息队列的优缺点

优点:

缺点:

三、消息队列的实现原理

四、消息队列的使用场景

五、消息队列的编程实现(C语言示例)

1. 创建消息队列

2. 发送消息

3. 接收消息

4. 删除消息队列

六、总结


        在现代操作系统中,进程间通信(IPC)是一个至关重要的主题。不同的进程需要相互交换数据、同步执行,而消息队列作为一种常见的IPC机制,为我们提供了一个灵活且高效的解决方案。本文将详细介绍消息队列的工作原理、使用场景以及具体的编程实现。

一、什么是消息队列?

        消息队列(Message Queue)是一种用于进程间通信的机制,它允许一个或多个进程通过向队列发送或接收消息的方式进行通信。消息队列遵循先进先出(FIFO)的原则,即消息按照它们被发送的顺序依次被处理。

消息队列的主要特点包括:

  1. 异步性:发送方和接收方可以并发运行,发送方不必等待接收方读取消息后才能继续运行。
  2. 数据缓冲:消息队列可以存储一定数量的消息,接收方可以根据需要读取消息。
  3. 持久性:消息队列中的消息可以持久化存储,除非显式删除或进程结束,消息队列不会立即消失。

二、消息队列的优缺点

优点:

  1. 异步通信:进程无需同步进行,可以随时发送和接收消息。
  2. 简化通信模型:消息队列提供了简单的接口,能够轻松实现进程间的通信,且支持多个进程共享队列。
  3. 消息存储:消息在队列中有序存储,接收方可以根据需求取出。

缺点:

  1. 容量有限:消息队列的容量有限,过多的消息可能导致阻塞或失败。
  2. 效率问题:在高并发情况下,消息队列的操作效率可能低于共享内存等方式。
  3. 系统资源消耗:系统为管理消息队列分配额外的内存和资源,可能带来一定的开销。

三、消息队列的实现原理

消息队列是通过内核提供的系统调用创建的,消息队列的基本操作包括:

  1. 创建消息队列:通过系统调用msgget()创建或获取一个消息队列。
  2. 发送消息:通过系统调用msgsnd()向消息队列发送消息。
  3. 接收消息:通过系统调用msgrcv()从消息队列接收消息。
  4. 控制消息队列:通过系统调用msgctl()控制消息队列,比如删除消息队列或查看消息队列的状态。

每个消息队列在系统中都有一个唯一的消息队列ID,通过这个ID,进程可以进行消息的发送和接收操作。

四、消息队列的使用场景

消息队列广泛用于进程间的解耦和异步通信,适合以下场景:

  1. 生产者-消费者模型:一个进程生产数据,另一个进程消费数据,消息队列可以缓冲数据,适应不同的处理速度。
  2. 分布式系统:消息队列可以在不同的计算机之间传递消息,用于微服务、分布式任务调度等场景。
  3. 任务调度系统:消息队列可以存储任务,调度系统从中取出并分发给工作进程处理。

五、消息队列的编程实现(C语言示例)

下面通过C语言示例展示如何在Linux系统中创建、发送和接收消息。

1. 创建消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

int main() {
    key_t key;
    int msgid;

    // 创建唯一的键值
    key = ftok("progfile", 65);

    // 创建消息队列,返回消息队列ID
    msgid = msgget(key, 0666 | IPC_CREAT);

    printf("消息队列ID: %d\n", msgid);

    return 0;
}

2. 发送消息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>

// 定义消息结构体
struct msg_buffer {
    long msg_type;
    char msg_text[100];
} message;

int main() {
    key_t key;
    int msgid;

    // 创建唯一的键值
    key = ftok("progfile", 65);

    // 获取消息队列ID
    msgid = msgget(key, 0666 | IPC_CREAT);

    // 准备发送的消息
    message.msg_type = 1;
    strcpy(message.msg_text, "Hello, this is a message");

    // 发送消息
    msgsnd(msgid, &message, sizeof(message), 0);

    printf("消息发送成功: %s\n", message.msg_text);

    return 0;
}

3. 接收消息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

// 定义消息结构体
struct msg_buffer {
    long msg_type;
    char msg_text[100];
} message;

int main() {
    key_t key;
    int msgid;

    // 创建唯一的键值
    key = ftok("progfile", 65);

    // 获取消息队列ID
    msgid = msgget(key, 0666 | IPC_CREAT);

    // 接收消息
    msgrcv(msgid, &message, sizeof(message), 1, 0);

    // 打印接收到的消息
    printf("接收到的消息: %s\n", message.msg_text);

    return 0;
}

4. 删除消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

int main() {
    key_t key;
    int msgid;

    // 创建唯一的键值
    key = ftok("progfile", 65);

    // 获取消息队列ID
    msgid = msgget(key, 0666 | IPC_CREAT);

    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);

    printf("消息队列已删除\n");

    return 0;
}

六、总结

        消息队列作为一种常用的进程间通信方式,具有异步通信、数据缓冲和持久化存储的特点,适用于生产者-消费者模型等场景。通过系统调用,我们可以方便地创建、发送、接收和控制消息队列。尽管消息队列有一些限制,比如容量有限、系统资源消耗较高,但在处理复杂的进程通信时,依然是一个高效且灵活的选择。

        希望这篇文章对你理解消息队列有所帮助。下一步可以探索更多高级的进程间通信方式,例如共享内存和信号量等。

标签:队列,msgid,间通信,详解,消息,key,message,include
From: https://blog.csdn.net/2201_75782847/article/details/142068168

相关文章

  • Linux iostat 命令详解
    Linuxiostat命令详解在Linux系统管理中,监控磁盘I/O性能是一项至关重要的任务。iostat是sysstat包中的一个实用工具,用于监控和显示系统输入输出设备和CPU的使用情况。它提供了丰富的数据,帮助系统管理员识别并解决潜在的I/O瓶颈问题。本文将详细介绍iostat命令的使用方法和关键参......
  • 线程池以及详解使用@Async注解异步处理方法
    目录一.什么是线程池:二.使用线程池的好处:三.线程池的使用场景:四.使用线程池来提高Springboot项目的并发处理能力:1.在application.yml配置文件中配置:2.定义配置类来接受配置文件内的属性值:3.启用异步支持:4.实例: 五.详细解析@Async注解的使用:1.@Async注解作用:2.@Asyn......
  • Kafka集群搭建与基本原理详解
    目录一、Kafka介绍1、MQ的作用MQ的作用主要有以下三个方面:1.异步2.解耦3.削峰2、为什么要用Kafka(特点)二、Kafka快速上手1、实验环境2、单机服务体验1、启动Kafka之前需要先启动Zookeeper。2、启动Kafka。3、简单收发消息4、其他消费模式指定消费进度分组......
  • 平台开发到落地详解:从食堂采购系统源码到可视化供应链管理数据大屏
    随着数字化转型的加速,越来越多的企业和组织开始重视供应链的智能化与可视化管理。在食堂采购领域,供应链管理的复杂性与日俱增,而传统的手工操作往往效率低下、容易出错。因此,开发食堂采购系统并结合可视化数据大屏的解决方案,成为了许多企业提高运营效率、优化采购流程的关键手段。 ......
  • Go语言中的队列与栈:基础与实践
    在日常编程中,数据结构是不可或缺的一部分。无论是开发复杂的系统,还是编写小型工具,选择合适的数据结构都能显著提高程序的效率和可读性。在Go语言中,队列和栈是两种常用的基础数据结构。本文将详细介绍如何在Go中实现队列与栈,并补充一些扩展内容,以帮助大家更好地理解和应用这......
  • QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]
    QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]第二期介绍:频道模块之频道管理目录QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]第二期介绍:频道模块之频道管理获取用户详情获取用户频道列表获取频道详情获取子频道列表获取子频道详情创建子频......
  • QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]
    QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]第三期介绍:频道模块之频道成员目录QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]第三期介绍:频道模块之频道成员获取子频道在线成员数获取频道成员列表获取频道身份组成员列表获取频道成员详情删......
  • Linux Makefile文件名处理函数知识详解
    GNUmake提供了一系列对文件名进行各种操作的函数:文件名替换、加前缀、去目录等。1.1dir函数:取路径名的目录dir函数用来从一个路径名中截取目录的部分。$(dirNAMES…)dir函数会从NAMES文件名序列中,取出各个文件路径名中的目录部分并返回.PHONY:allLIST=/home/wit/ban......
  • MySQL timestamp和datetime用法详解
    一、MySQL中如何表示当前时间?其实,表达方式还是蛮多的,汇总如下:CURRENT_TIMESTAMPCURRENT_TIMESTAMP()NOW()LOCALTIMELOCALTIME()LOCALTIMESTAMPLOCALTIMESTAMP() 二、关于TIMESTAMP和DATETIME的比较一个完整的日期格式如下:YYYY-MM-DDHH:MM:SS[.fraction],它可分为两部......
  • 【Java 分支语句详解 之 If 】
    Java分支语句详解之If-else在编程过程中,我们经常需要根据不同的条件执行不同的代码块,这种流程控制被称为分支语句。在Java中,常见的分支控制结构有if-else和switch。本文将详细介绍if分支结构的使用方法以及相关的代码示例。一、单分支控制语句(if)基本语......