Linux进程如何通过消息队列实现进程间通信 (linux 进程 消息队列)

Linux作为一种优秀的操作系统,它鼓励进程之间的交互,而进程间通信是进程交互的一种方式。在Linux中,进程间通信(IPC)是一种进程之间交换数据和信息的技术,这种技术包括多个子技术,如管道、套接字、共享内存、消息队列等。在本篇文章中,我们将介绍如何使用Linux消息队列实现进程间通信。

1. 什么是消息队列

在计算机系统中,消息队列是一种用于进程间通信的系统调用,它允许多个进程通过消息来进行通信。消息队列是一个存放消息的队列,其中每个消息都有一个特定的类型和一个消息体。多个进程可以通过消息队列进行信息交换,发送者将消息放入队列,而接收者则从队列中读取消息。消息队列是一种异步通信机制,因为发送者不需要等待接收者读取其消息。

2. 创建和操作消息队列

创建消息队列的函数为msgget(),该函数需要一个键值和一些标志来创建一个消息队列。可以使用ftok()函数将文件路径和一个id作为输入,生成一个唯一的键值,用于识别消息队列。

int msgget(key_t key, int msg);

key是由ftok()函数生成的键值, msg表示创建消息队列的选项。

成功创建消息队列后,我们可以使用msgsnd()向消息队列发送消息。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg);

msqid是一个标识消息队列的整数,msgp是指向消息结构的指针,msgsz是消息的长度,msg是消息发送的选项。当发送失败时,msgsnd()返回-1。

接收消息时,可以使用msgrcv()函数。msgrcv()函数从消息队列中读取一个消息,如果消息队列中没有消息,则会阻塞等待消息的到来。

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msg);

msqid是标识消息队列的整数,msgp是指向消息缓冲区的指针,msgsz是消息缓冲区的大小,msgtyp是要读取的消息类型,msg是消息接收的选项。当接收失败时,msgrcv()返回-1。

3. 示例程序

以下是一个示例程序,用于说明如何在进程之间使用消息队列来传递信息。在本例中,我们有两个程序,一个程序用于发送消息,另一个程序用于接收消息。

消息队列示例代码如下:

#include

#include

#include

#include

#include

#define MAX_TEXT 512

struct message {

long msg_type;

char msg_text[MAX_TEXT];

};

int mn() {

struct message msg;

int msgid;

//创建键值

key_t key = ftok(“.”, ‘a’);

//创建消息队列

msgid = msgget(key, IPC_CREAT | 0666);

if (msgid == -1) {

printf(“Fled to create message queue.”);

return -1;

}

printf(“Type a message to send: “);

fgets(msg.msg_text, MAX_TEXT, stdin);

msg.msg_type = 1;

//发送消息

if (msgsnd(msgid, &msg, strlen(msg.msg_text) + 1, 0) == -1) {

printf(“Fled to send message.”);

return -1;

}

printf(“Message sent: %s”, msg.msg_text);

return 0;

}

接收消息的程序示例代码:

#include

#include

#include

#include

#include

#include

#define MAX_TEXT 512

struct message {

long msg_type;

char msg_text[MAX_TEXT];

};

int mn() {

struct message msg;

int msgid;

//创建键值

key_t key = ftok(“.”, ‘a’);

//创建消息队列

msgid = msgget(key, IPC_CREAT | 0666);

if (msgid == -1) {

printf(“Fled to create message queue.”);

return -1;

}

//接收消息

if (msgrcv(msgid, &msg, MAX_TEXT, 1, 0) == -1) {

printf(“Fled to receive message.”);

return -1;

}

printf(“Message received: %s”, msg.msg_text);

//删除消息队列

if (msgctl(msgid, IPC_RMID, NULL) == -1) {

printf(“Fled to delete message queue.”);

return -1;

}

return 0;

}

4.

使用Linux消息队列进行进程间通信是一种可靠和灵活的方式。消息队列提供异步通信,因此在发送消息时不需要等待接收者读取消息。使用消息队列的主要优点是,具有高效、快速、可靠和可扩展性,可以处理大量数据和多个进程的并发请求。

在使用消息队列时,需要注意的问题是,要确保消息队列的一致性和可靠性,即保证消息发送时发生的错误可以得到处理和纠正。同时,也需要注意避免消息队列拥塞和垃圾信息的产生。

相关问题拓展阅读:

Binder机制概述

Android进程间通讯是通过Binder机制来实现的,Android是基于linux系统因此有必要了解Linux系统进程相关知识.

Linux系统中(其他系统也是这样)不同进程之间不允许直接操作或访问另一进程.也就是进程隔离.

为了保证用户进程不能直接访问内核,操作系统从逻辑上将虚拟空间划分为用户空间和内核空间.内核程序运行在内核空间(kernel space),应用程序运行在用户空间(user space).为了安全,他们之间是隔离的,即使用户程序奔溃了,也不会影响内核.内核空间数据是可以共享的,用户空间不可以.

用户空间访问内核空间只能通过系统调用,系统调用是用户空间访问内核空间的唯一方式,保证所有资源访问在内核控制下,避免了用户对系统资源的越权访问,提高了系统安全性和稳定性.

copy_from_user:将用户空间数据拷贝到内核空间

copy_to_user:将内核空间数据拷贝到用户空间

由于用户进程不能直接访问硬件地址,所以系统提供了一种机制:内存映射(Memory Map).在Linux中通过调用函数mmap实现内存映射,将用户空间一块内存地址映射到内核空间.映射关系建立后,对用户空间内存的修改可以反应到内核空间.内存映射可减少拷贝次数.

如果没有内存映射,用户进程需要访问硬盘文件时,需要在内核空间创建一片页缓存,将硬盘文件数据拷贝到页缓存然后用户进程在拷贝页缓存数据,需要两次拷贝.通过内存映射后硬盘文件可以和内核的虚拟内存直接映射,减少一次拷贝.

如图

inter-process-communication进程间通信,指进程间交换数据的过程.

Linux提供了很多进程间通讯的机制,主要有管道(pipe)、消息队列(Message)、信号(sinal)、信号量(semophore)、套接字(socket)等

内核程序在内核空间分配并开辟一块内核缓冲区,发送进程将数据通过copy_from_user拷贝到内核空间的数据缓冲区,内核空间通过copy_to_user将数据拷贝到接收进程,这样就实现了一次进程间通信.如图

Linux的IPC机制有两个问题:

1.数据通过用户空间->内核空间->用户空间,经过两次拷贝,效率不高

2.接伍裂收进程无法预先知道数据大小,只拿弊能尽可能大创建数据缓冲区,或腔敏闭通过api消息头获取消息体的大小,浪费了空间或时间.

Android进程间通信通过Binder实现,下面介绍Binder机制通信原理,为什么是Binder

内核程序创建一个数据接收缓存区,同时创建一个内核缓冲区.并建立内核缓冲区和数据接收缓冲区内存映射,以及数据内核缓冲区和接收进程用户空间的映射关系.发送进程通过copy_from_user将数据拷贝到内核数据接收缓冲区,因为内核数据接收缓冲区和内核缓冲区以及接收进程用户空间存在映射关系,相当于将数据发送到了接收进程.完成了一次进程间通信.如图

Binder机制是c/s架构的,由Client、server、ServiceManager和Binder组成.client、server和serviceManager都是独立的进程,由于Linux进程隔离的原因,所以需要借助Binder进行通信.

Binder通信主要有三个步骤:注册服务、获取服务、使用服务.如下图

从上一条Binder实现原理示例图中可以看到,Binder可分为Java Binder、Native Binder和Kernal Binder.应用开发需要了解Java Binder和Navive Binder.这里只介绍Binder基本原理.具体可查看文章结尾的链接.

感谢

all first_rank_ecpm_v3~rank_business_v.ecpm_v3_rank_business_v1&utm_term=Binder&spm=1018.2118.3001.4187

linux 进程 消息队列的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux 进程 消息队列,Linux进程如何通过消息队列实现进程间通信,Binder机制概述的信息别忘了在本站进行查找喔。


数据运维技术 » Linux进程如何通过消息队列实现进程间通信 (linux 进程 消息队列)