LinuxIPC通信消息队列(C+Python实现)

本文深入探讨了消息队列作为SystemV进程间通信机制之一的角色,对比了其与信号量、共享存储段及管道的区别。详细介绍了消息队列的工作原理,包括其基于消息而非字节流的特点,以及在客户/服务器模型中的应用。此外,文章还讲解了Python的multiprocessing模块中队列类的使用,以及C语言中实现消息队列的具体API。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息队列是SystemV版本中三种进程通信机制之一,另外两种是信号量和共享存储段。消息队列提供了进程间发送数据块的方法,而且每个数据块都有一个类型标识。消息队列是基于消息的,而管道是基于字节流。创建的消息队列,生命周期随内核,只有内核重启或用户主动去删除,才可以真正关闭消息队列。

  一个或多个进程可向消息队列写入消息,而一个或多个进程可从消息队列中读取消息,这种进程间通讯机制通常使用在客户/服务器模型中,客户向服务器发送请求消息,服务器读取消息并执行相应请求。在许多微内核结构的操作系统中,内核和各组件之间的基本通讯方式就是消息队列。例如,在 MINIX 操作系统中,内核、I/O 任务、服务器进程和用户进程之间就是通过消息队列实现通讯的。

Python:

Python 的 multiprocessing 模块中提供了同步的、线程安全的队列类,FIFO(先入先出)队列Queue。 

python queue模块有三种队列:
1、python queue模块的FIFO队列先进先出。
2、LIFO类似于堆。即先进后出。
3、还有一种是优先级队列级别越低越先出来。 

针对这三种队列分别有三个构造函数:
1、class Queue.Queue(maxsize) FIFO 
2、class Queue.LifoQueue(maxsize) LIFO 
3、class Queue.PriorityQueue(maxsize) 优先级队列 

Queue 模块中的常用方法:

Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
 

#!/usr/bin/python3

import multiprocessing

def put_queue(queue):
    for i in range(5):
        queue.put(i)
        
def get_queue(queue):
    while not queue.empty():
        print(queue.get())

queue = multiprocessing.Queue()

put_p = multiprocessing.Process(target=put_queue,args=(queue,))
get_p = multiprocessing.Process(target=get_queue,args=(queue,))
put_p.start()
put_p.join()
get_p.start()

C:

int msgget(key_t key, int msgflg);

获取消息队列还是获取共享内存,就像打开文件一样,这个文件可能存在也可能不存在。

获取一个消息队列之后会返回一个消息队列的句柄

操作消息队列

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

消息队列的发送
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);

#include <signal.h>
#include "head4msg.h"

int main(int argc, char **argv)
{
	key_t key = ftok(PROJ_PATH, PROJ_ID);
	int msgid = msgget(key, IPC_CREAT | 0666);

	struct msgbuf buf;
	bzero(&buf, sizeof(buf));

	if(msgrcv(msgid, &buf, MSGSIZE, J2R, 0) == -1)
	{
		perror("msgrcv() error");
		exit(1);
	}
	printf("from msg: %s", buf.mtext);

	msgctl(msgid, IPC_RMID, NULL);
	return 0;
}
#include "head4msg.h"

int main(int argc, char **argv)
{
	key_t key = ftok(PROJ_PATH, PROJ_ID);
	int msgid = msgget(key, IPC_CREAT | 0666);

	struct msgbuf message;
	bzero(&message, sizeof(message));

	message.mtype = J2R;
	strncpy(message.mtext, "abcxyz\n", MSGSIZE);

	if(msgsnd(msgid, &message, strlen(message.mtext), 0) != 0)
	{
		perror("msgsnd() error");
		exit(1);
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值