慢吞云雾缓吐愁 发表于 2025-10-28 10:24:53

【嵌入式Linux应用开辟底子】历程间通讯(2):消息队列

目次
一、消息队列概述
二、Linux 消息队列干系体系调用
2.1. msgget
2.2. msgsnd
2.3. msgrcv
2.4. msgctl
三、消息队列使用示例
3.1. 发送历程示例代码
3.2. 吸收历程示例代码
四、消息队列的优缺点
4.1. 优点
4.2. 缺点
五、关键留意事项
六、常见题目
5.1. 怎样创建消息队列?
5.2. 怎样向消息队列中添加消息?
5.3. 怎样从消息队列中读取消息?
5.4. 怎样控制消息队列(如删除)?
5.5. 消息队列的键值(key)是怎样天生的?
5.6. 消息队列的优先级和范例是怎样工作的?
5.7. 消息队列的同步和互斥题目怎样办理?
七、总结
八、参考资料
在嵌入式Linux应用开辟中,历程间通讯(IPC)是一个紧张的概念。消息队列作为IPC的一种机制,允许历程之间以消息的情势发送和吸收数据。
一、消息队列概述

在嵌入式 Linux 应用开辟中,历程间通讯(IPC)是实现多历程协同工作的关键。消息队列作为一种紧张的 IPC 机制,为历程间的数据交换提供了一种异步、可靠的方式。消息队列允许一个或多个历程向队列中发送消息,也可以从队列中吸收消息,而且每个消息都可以有一个特定的范例,吸收者可以根据消息范例有选择地吸收消息。
特点:


[*]异步通讯:发送历程可以在发送消息后继承实行其他任务,不须要期待吸收历程立刻处置惩罚消息,进步了历程的实行服从。
[*]消息分类:消息队列中的消息可以根据范例举行分类,吸收历程可以根据须要选择吸收特定范例的消息,方便实现差别范例数据的转达和处置惩罚。
[*]长期化:消息队列可以在体系中长期存在,纵然发送和吸收历程暂时退出,消息仍然可以保存在队列中,期待后续处置惩罚。
二、Linux 消息队列干系体系调用

2.1. msgget

用于创建或获取一个消息队列。
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg); 参数阐明:


[*] key:消息队列的键值,可以通过ftok函数天生,也可以使用IPC_PRIVATE来创建一个私有的消息队列。
[*] msgflg:标志位,用于指定消息队列的创建方式和权限,常见的标志有IPC_CREAT(如果消息队列不存在则创建)、IPC_EXCL(与IPC_CREAT一起使用,若队列已存在则返回错误)等。
返回值:乐成时返回消息队列的标识符(非负整数),失败时返回 -1,并设置errno。
2.2. msgsnd

用于向消息队列中发送消息。
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数阐明:


[*]msqid:消息队列的标识符,由msgget函数返回。
[*]msgp:指向消息缓冲区的指针,消息缓冲区必须是一个布局体,且布局体的第一个成员必须是long范例,用于指定消息的范例。
[*]msgsz:消息的长度,不包罗消息范例的长度。
[*]msgflg:标志位,常见的标志有IPC_NOWAIT(如果消息队列已满,不期待直接返回错误)等。
返回值:乐成时返回 0,失败时返回 -1,并设置errno。
2.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); 参数阐明:


[*]msqid:消息队列的标识符。
[*]msgp:指向消息缓冲区的指针,用于存储吸收到的消息。
[*]msgsz:消息缓冲区的最大长度。
[*]msgtyp:指定要吸收的消息范例,可以根据须要选择吸收特定范例的消息。
[*]msgflg:标志位,常见的标志有IPC_NOWAIT(如果队列中没有指定范例的消息,不期待直接返回错误)、MSG_NOERROR(如果消息长度高出msgsz,截断消息而不返回错误)等。
返回值:乐成时返回吸收到的消息的实际长度(不包罗消息范例的长度),失败时返回 -1,并设置errno。
2.4. msgctl

用于对消息队列举行控制操纵,如删除消息队列等。
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf); 参数阐明:


[*]msqid:消息队列的标识符。
[*]cmd:控制下令,常见的下令有IPC_RMID(删除消息队列)、IPC_STAT(获取消息队列的状态信息)等。
[*]buf:用于存储消息队列状态信息的布局体指针,当cmd为IPC_STAT时使用。
返回值:乐成时返回 0,失败时返回 -1,并设置errno。
三、消息队列使用示例

3.1. 发送历程示例代码

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

#define MSG_SIZE 100
#define QUEUE_KEY 1234

// 消息结构体
typedef struct {
    long msg_type;
    char msg_text;
} Message;

int main() {
    int msqid;
    Message msg;

    // 创建或获取消息队列
    msqid = msgget(QUEUE_KEY, IPC_CREAT | 0666);
    if (msqid == -1) {
      perror("msgget");
      exit(1);
    }

    // 填充消息内容
    msg.msg_type = 1;
    strcpy(msg.msg_text, "Hello, message queue!");

    // 发送消息
    if (msgsnd(msqid, &msg, strlen(msg.msg_text) + 1, 0) == -1) {
      perror("msgsnd");
      exit(1);
    }

    printf("Message sent successfully.\n");

    return 0;
} 3.2. 吸收历程示例代码

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

#define MSG_SIZE 100
#define QUEUE_KEY 1234

// 消息结构体
typedef struct {
    long msg_type;
    char msg_text;
} Message;

int main() {
    int msqid;
    Message msg;

    // 获取消息队列
    msqid = msgget(QUEUE_KEY, 0666);
    if (msqid == -1) {
      perror("msgget");
      exit(1);
    }

    // 接收消息
    if (msgrcv(msqid, &msg, MSG_SIZE, 1, 0) == -1) {
      perror("msgrcv");
      exit(1);
    }

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

    // 删除消息队列
    if (msgctl(msqid, IPC_RMID, NULL) == -1) {
      perror("msgctl");
      exit(1);
    }

    return 0;
} 四、消息队列的优缺点

4.1. 优点



[*]异步通讯:发送和吸收历程可以独立实行,进步了体系的并发性能。
[*]消息分类:可以根据消息范例有选择地吸收消息,方便实现差别范例数据的处置惩罚。
[*]长期化:消息可以在队列中保存,直到被吸收或删除,包管了数据的可靠性。
4.2. 缺点



[*]体系开销:消息队列的创建、维护和管理须要肯定的体系资源,对于资源有限的嵌入式体系大概会造成肯定的负担。
[*]消息巨细限定:每个消息的巨细通常有肯定的限定,对于大数据的传输大概须要举行分段处置惩罚。
[*]性能题目:在高并发场景下,消息队列的性能大概会受到影响,须要举行公道的优化。 
五、关键留意事项



[*]在使用消息队列举行历程间通讯时,须要确保发送和吸收历程都使用雷同的键值来创建或打开消息队列,以确保它们可以或许准确地交换消息。
[*]消息队列的巨细是有限的,因此须要留意制止消息队列溢出或消息丢失的题目。可以通过监控消息队列的状态和实时调解队列巨细来办理这些题目。
[*]在使用msgctl函数删除消息队列时,须要确保没有其他历程正在使用该队列,否则大概会导致未界说的活动或数据丢失。
六、常见题目

5.1. 怎样创建消息队列?

在嵌入式Linux中,可以使用msgget函数来创建或打开一个消息队列。该函数须要两个参数:一个是由ftok函数天生的唯一键值(key),另一个是标志位(flag),用于指定创建消息队列时的权限和是否创建新队列等。如果消息队列已存在,则msgget会返回该队列的ID;如果不存在且指定了创建标志,则会创建一个新的消息队列。
5.2. 怎样向消息队列中添加消息?

使用msgsnd函数可以向消息队列中添加消息。该函数须要四个参数:消息队列的ID、指向消息内容的指针、消息的巨细以及标志位。如果添加乐成,函数返回0;如果失败,则返回-1并设置errno以指示错误缘故原由。
5.3. 怎样从消息队列中读取消息?

使用msgrcv函数可以从消息队列中读取消息。该函数也须要四个参数:消息队列的ID、指向用于存储吸收到的消息的缓冲区的指针、缓冲区的巨细、消息的范例以及标志位。如果读取乐成,函数返回吸收到的消息的长度;如果失败,则返回-1并设置errno以指示错误缘故原由。
5.4. 怎样控制消息队列(如删除)?

使用msgctl函数可以控制消息队列,包罗删除队列、获取队列属性等。该函数须要三个参数:消息队列的ID、控制下令(如IPC_RMID用于删除队列)以及指向一个布局体的指针(该布局体用于存储或吸收队列的属性信息,如果不须要则可以转达NULL)。
5.5. 消息队列的键值(key)是怎样天生的?

消息队列的键值通常使用ftok函数天生。该函数须要两个参数:一个路径名(pathname)和一个子序号(id)。路径名通常是一个文件的路径,而子序号是一个整型值(但只使用其低8位)。ftok函数根据这两个参数天生一个唯一的键值,该键值可以用于创建或打开消息队列。
5.6. 消息队列的优先级和范例是怎样工作的?

在消息队列中,每条消息都有一个范例(type)和一个优先级(固然在实际使用中优先级并不总是被明确区分或使用)。消息的范例是一个长整型值,可以用于指定消息的分类或处置惩罚逻辑。在读取消息时,可以通过指定消息的范例来过滤或选择性地吸收消息。
5.7. 消息队列的同步和互斥题目怎样办理?

消息队列本身提供了一种同步机制,由于发送和吸收消息的操纵都是原子性的。然而,在多个历程同时访问同一个消息队列时,仍然须要思量同步和互斥题目以制止竞态条件。这通常可以通过使用信号量、互斥锁等同步机制来实现。
七、总结

消息队列作为一种紧张的历程间通讯机制,在嵌入式 Linux 应用开辟中具有广泛的应用远景。通过公道使用消息队列,可以实现历程间的异步通讯、数据转达和任务调治,进步体系的并发性能和可靠性。但在使用过程中,也须要留意体系开销、消息巨细限定和性能题目等方面的影响,根据实际需求举行公道的筹划和优化。
八、参考资料



[*]《Unix 环境高级编程(第 3 版)》

[*]作者:W. Richard Stevens、Stephen A. Rago
[*]简介:经典的 Unix 和类 Unix 体系编程著作,具体论述了 Unix 环境下的各种编程接口和技能,此中对消息队列的解说深入浅出,包罗体系调用的原理、使用方法和示例代码。

[*]《Linux 体系编程》

[*]作者:Robert Love
[*]简介:专注于 Linux 体系编程的技能细节,对 Linux 内核和用户空间编程有深入的探究。

[*]《嵌入式 Linux 应用开辟完全手册》

[*]作者:韦东山
[*]简介:精密围绕嵌入式 Linux 应用开辟,从实际项目出发,具体先容了消息队列在嵌入式体系中的应用场景、开辟流程和调试本领,配有丰富的实例代码和项目案例,对嵌入式开辟者具有很强的引导意义。

[*]Linux 手册页

[*]获取方式:在 Linux 体系终端使用man下令,如man msgget、man msgsnd等查察消息队列干系体系调用的手册页;也可访问man7.org在线查察。
[*]简介:最权势巨子的 Linux 体系调用参考资料,提供了消息队列干系体系调用的具体信息,包罗函数原型、参数阐明、返回值、使用示例和错误处置惩罚等,是学习和使用消息队列的紧张依据。

[*]GNU C Library 文档

[*]获取方式:访问GNU 官方网站。
[*]简介:GNU C Library 是 Linux 体系广泛使用的 C 尺度库。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【嵌入式Linux应用开辟底子】历程间通讯(2):消息队列