首页 > 系统相关 >《Linux系统编程篇》消息队列(Linux 进程间通信(IPC))——基础篇

《Linux系统编程篇》消息队列(Linux 进程间通信(IPC))——基础篇

时间:2024-11-01 19:19:33浏览次数:3  
标签:IPC 删除 队列 间通信 int 消息 Linux msg message

文章目录

“山重水复疑无路,柳暗花明又一村。” ——陆游

引言

《Linux系统编程篇》——基础篇首页传送门
想象一下,你正在开发一个多任务处理的应用程序,其中需要不同的模块之间进行数据交换和协作。这时,消息队列就像是一个快递站,负责接收、存储和转发各个模块之间的信息。发送者将消息放入队列,接收者则可以从队列中取出消息并进行处理,实现了模块之间的解耦和异步通信。

消息队列(Message Queue)

消息队列是一种更高级的 IPC 方式,允许多个进程之间以消息的形式进行数据交换。消息队列提供了有序的数据传输,并且允许对消息进行优先级排序。

消息队列是存放消息的链表,他存在于Linux内核当中,每一个消息队列用一个标识符也就是队列id来标识。

消息队列的特点

1、消息队列可以独立发送与接受,成功创建后,如果进程结束,消息队列节点并不会消失,他的消失是由Linux内核 来管理的
2、消息队列是面向记录的,有特定格式及特点的优先级
3、消息队列可以实现消息的随机查询,消息不一定要以先进先出的顺序依次读取,也可以使用消息类型读取。

消息队列的特性

  • 异步通信:发送方和接收方不需要同时在线,可以分别发送和接收消息。

  • 消息缓存:消息队列可以缓存一定数量的消息,接收方可以按需处理。

  • 消息优先级:消息队列通常支持消息的优先级设定,确保重要消息被优先处理。

  • 消息持久性:消息队列通常支持消息的持久化,即使接收方不在线,消息也不会丢失。

函数原型及结构体

typedef struct msgbuf {
        long mtype;       /* message type, must be > 0 */
        char mtext[128];    /* message data */
}msg;
//获取消息队列id号
int msgget(key_t key, int msgflg);
//发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//接受消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
//控制队列(用来销毁)
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

一图带你了解消息队列
在这里插入图片描述

消息队列的操作

  • 创建消息队列:使用msgget系统调用创建消息队列,返回一个标识符(消息队列ID)。

  • 发送消息:使用msgsnd系统调用向消息队列发送消息。

  • 接收消息:使用msgrcv系统调用从消息队列接收消息。

  • 删除消息队列:使用msgctl系统调用删除不再需要的消息队列。

用法

  1. 使用 msgget() 创建或获取消息队列。
  2. 使用 msgsnd() 发送消息,msgrcv() 接收消息。
  3. 消息队列通过键值(key)来标识,且在内核中驻留。

示例代码:

本次的示例代码为单进程,可以分为两个文件,实现多进程的消息队列通讯,学员们可以自己动手敲一下感受一下。

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

struct msg_buffer {
    long msg_type;
    char msg_text[100];
} message;

int main() {
    key_t key = ftok("progfile", 65); // 生成消息队列键
    int msgid = msgget(key, 0666 | IPC_CREAT); // 创建消息队列

    // 向消息队列发送消息
    message.msg_type = 1;
    strcpy(message.msg_text, "Hello from sender!");
    msgsnd(msgid, &message, sizeof(message), 0);

    printf("Sent message: %s\n", message.msg_text);

    // 接收消息
    msgrcv(msgid, &message, sizeof(message), 1, 0);
    printf("Received message: %s\n", message.msg_text);

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

运行结果
在这里插入图片描述

ipcs -q 拓展

在Linux系统中,可以使用ipcs命令来查看系统中的消息队列信息。ipcs命令可以列出系统中当前存在的进程间通信(IPC)对象,包括消息队列、信号量和共享内存。

信号量和共享内存我们以后会介绍到。

ipcs -q

这将列出系统中所有的消息队列,包括它们的标识符(ID)、拥有者、权限、大小等信息。您可以通过这些信息了解系统中消息队列的使用情况。
在这里插入图片描述
如果在上述代码中不删除则会
在这里插入图片描述

ipcrm 拓展

在Linux系统中,您可以使用ipcrm命令手动删除消息队列。ipcrm命令用于删除System V IPC 对象(包括消息队列、信号量和共享内存)。

要手动删除消息队列,您需要知道消息队列的标识符(ID)。首先,您可以使用ipcs -q命令列出系统中的消息队列及其ID,然后选择要删除的消息队列的ID。

ipcrm -q <queue_id>

其中,<queue_id> 是要删除的消息队列的标识符(ID)。

例如,如果要删除标识符为12345的消息队列,您可以运行以下命令:

ipcrm -q 12345

比如我要手动删除我刚刚没有删除的的消息队列。
在这里插入图片描述

注意事项

  1. 消息格式一致性:发送和接收进程之间必须约定好消息的格式,包括消息的大小、结构和编码方式。确保发送的消息可以被接收进程正确解析和处理。

  2. 消息队列容量:消息队列有容量限制,当消息队列满时,发送进程可能被阻塞或消息被丢弃。需要根据实际需求设置合适的消息队列容量,避免消息丢失或系统阻塞。

  3. 进程同步:在使用消息队列进行通信时,需要考虑进程之间的同步和互斥,避免出现竞争条件和数据不一致的情况。可以使用信号量等机制来实现进程间的同步。


结论

消息队列通常用于进程间通信,特别是在需要解耦发送者和接收者、实现异步通信的情况下。

通过学习消息队列,希望学员们将能够更好地理解并应用进程间通信的技术,为构建复杂的软件系统打下坚实的基础。

标签:IPC,删除,队列,间通信,int,消息,Linux,msg,message
From: https://blog.csdn.net/qq_52749711/article/details/143436515

相关文章

  • Chromium127编译指南 Linux篇 - 同步第三方库以及Hooks(六)
    引言在成功克隆Chromium源代码仓库并建立新分支之后,配置开发环境成为至关重要的下一步。这一过程涉及获取必要的第三方依赖库以及设置钩子(hooks),这些步骤对于确保后续的编译和开发工作能够顺利进行起着决定性作用。本指南旨在详细阐述这些配置步骤的执行方法,为开发者提供清晰......
  • Chromium127编译指南 Linux篇 - 编译前环境搭建(一)
    前言在当前的浏览器开发中,Chromium作为一个开源项目,已经赢得了广泛的关注和使用。它不仅构成了GoogleChrome的核心框架,同时也是诸如MicrosoftEdge、Opera和Brave等多款浏览器的基础。凭借其广泛的应用和出色的可定制性,许多开发者选择在Chromium的基础上进行再开发......
  • Linux nginx 配置
    Nginx的配置类型丰富多样,可以根据不同的需求进行灵活配置。以下是使用不同域名介绍的10种Nginx配置类型:基本Web服务器配置域名:http://www.example1.com配置说明:这是Nginx作为Web服务器的基本配置,包括监听端口、服务器名称、根目录设置等。示例配置:nginxserver{ listen8......
  • Linux-shell实例手册-网络操作
    本文章讲解的是在linux下跟网络相关的一些操作和命令,喜欢就点赞收藏哦,方便随时查阅!文章目录1Linux下网络基本命令2netstat3ssh4网卡配置文件5route6解决ssh链接慢7ftp上传8nmap9 流量切分线路10snmp1Linux下网络基本命令   rz  #通过ssh上传......
  • Linux的常用命令
    普通用户不具备修改权限命令su-(进入root账号)查询资料是因为$代表普通用户模式,权限不够,可以进入root帐号在建立文件夹进入root帐号,打su-(su-切换到root用户,并转到root用户的家目录下,即改变到了root用户的环境。)命令选项传参command-optionsparameterCommand:命......
  • 【Linux】动静态库(超详细)
     ......
  • Linux sshd升级
    1.ubuntussh升级到9.6sshd_update_ubt#定义变量dir="/etc/xinetd.d/"sshd_pid=`ps-ef|grepsshd|awk'$3==1{print$2}'`#结束sshd进程stop_sshd(){ [-z"${sshd_pid}"]||{ kill${sshd_pid} }}#下载telnetapt_telnet(){apt......
  • 100 道 Linux 常见面试题,慢慢读~_linux基础面试题
    1Linux概述1.1什么是LinuxLinux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络......
  • 【Linux内核】Cgroup原理和使用
    1.Cgroup简介cgroups(ControlGroups)是Linux内核的一个特性,用于对进程组的物理资源(如CPU、内存、磁盘I/O等)进行细粒度的控制和监控。cgroups可以帮助你限制、记录和隔离资源使用,但它本身并不直接用来“拉高CPU负载”。相反,cgroups通常用于限制进程可以使用的资源量,以防止它们消耗......
  • 截图工具 for Linux --- 你用过吗?
    截图工具forLinuxLinux系统在桌面、嵌入式、服务器等多领域的广泛应用,催生了各种需求的截图工具。从简单的命令行工具到复杂的图形化应用,Linux的截图工具逐渐发展并适应了不同的图形后端架构,如X11和Wayland。本篇将从这两大后端的视角出发,介绍Linux截图工具的种类、功能......