进程间通信 消息队列 函数用法介绍

Linux的消息队列是一种在进程间传递消息的数据结构。它允许一个进程将一条消息放入队列,而其他进程可以从队列中取出并处理消息。消息队列在实现进程间通信(IPC)方面非常有用。

IPC对象

IPC(InterProcess Communication) 对象是活动在内核级别的一种进程间通信的工具。IPC对象可以是消息队列、信号量或共享存储器中的任意一种类型。IPC对象通过标识符来引用和访问,这个标识符是一个非负整数,它唯一的标识了一个IPC对象。在Linux系统中,IPC对象的标识符被声明为整数,所以可能存在的最大标识符为65535。IPC对象删除或创建时相应的标识符的值会不断增加到最大的值,归零循环分配使用。如果用户需要使用IPC对象进行进程之间的通信,首先必须要为IPC对象申请对应资源(key值、ID号)。例如使用消息队列来通信,那么就必须为消息队列申请key值与ID号。

查看IPC对象。

命令:ipcs [-asmq]

选项功能
-a查看全部IPC对象信息
-m查看共享内存
-q查看消息队列
-s查看信号量集
  • IPC标识符

    内核分配给IPC对象,在系统内部唯一

  • IPC键(key)

    • IPC对象的外部表示,由程序员选择
    • IPC关键字是一个32位长整型数据,全局唯一
    • 通过同一个键,不同的进程可以访问同一个IPC对象
    • 每个进程都可以创建一个键值为IPC_PRIVAE的私有IPC对象
    • 可以通过调用函数ftok产生一个唯一的键值

ftok函数原型:

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(char* filename, int id);

参数说明:

  • filename:文件名,可以使用绝对路径相对路径
  • id:整型变量。

返回值:

  • 调用成功,返回生成的键值key
  • 调用失败,返回-1

消息队列

消息队列(Message Queue)是一种进程间通信或同一进程的不同线程间通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数。消息队列中的消息是先进先出(FIFO)的数据结构,也就是说,最先进入队列的消息将会最先被取出。每个消息队列都有一个最大长度,一旦达到最大长度,后续的入队操作将会失败。

消息队列是在消息的传输过程中保存消息的容器。它允许应用程序通过发送和接收消息来进行通信,这些消息按照它们到达的顺序存储在队列中。消息队列的主要目的是提供路由并保证消息的传递,如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。

消息队列在分布式系统中扮演着重要的角色,它们允许不同的应用程序或不同的组件之间进行通信和协作。通过使用消息队列,应用程序可以解耦和异步处理数据流,从而提高系统的可靠性和性能。

消息队列是:

  • 存储消息的链表
  • 消息队列中的每个消息可以视为一条记录
  • 新添加的消息总是在队尾,接收消息的进程可以读取队列中间的数据
  • 消息队列可实现无亲缘关系进程间的通信

消息结构

消息结构模板msgbuf

struct msgbuf
{
	long msgtype; // 消息的类型, 长整型变量
	char mtext[1]; // 消息的内容,字符串数组
}

该结构只是一个模板,在实际的编程中,可以根据该模板自行定义消息的长度。

消息队列通信的步骤

  1. 创建消息队列 msgget()
  2. 向消息队列发送消息 msgsnd()
  3. 从消息队列读取消息 msgrcv()
  4. 删除消息队列 msgctl()

msgget()

函数原型:

#include <sys/types.h>
#include <sys/msg.h>
int msgget(key_t key, int flags);

参数说明:

  • key:键值
    • 可以通过ftok函数产生
    • IPC_PRIVATE:创建当前进程的私有消息队列
  • flags:标识和权限信息的组合
    • IPC_CREAT:如果消息队列不存在,则创建一个新的队列;如果消息队列存在,则引用已存在的消息队列
    • 0:获取一个已存在的消息队列的标识符

返回值:

  • 调用成功,返回消息队列的标识符
  • 调用失败,返回-1

msgsnd()

函数原型:

#include <sys/types.h>
#include <sys/msg.h>
int msgsnd(int msqid, struct msgbuf* msgp, size_t size, int flag);

参数说明:

  • msqid:消息队列的标识符
  • msgp:指向消息结构指针
  • size:消息内容的长度
  • flag:发送消息可选标志
    • 0:当消息队列已满时,消息的发送操作阻塞,直到有进程从队列中读出消息
    • IPC_NOWAIT:当消息队列满时,进程不阻塞,立即返回-1

返回值:

  • 调用成功,返回0
  • 调用失败,返回-1

msgrcv()

函数原型:

#include <sys/types.h>
#include <sys/msg.h>
int msgrcv(int msqid, struct msgbuf* msgp, size_t size, long type, int flag);

参数说明:

  • msqid:消息队列的标识符
  • msgp:消息结构指针
  • size:要读取消息的长度
  • type:要读取消息的类型
  • flag:接收消息可选标志
    • 0:当消息队列为空时,进程阻塞
    • IPC_NOWAIT:表明当消息队列空时,进程不阻塞,立即返回-1
    • MSG_NOERROR:允许消息长度大于接收缓冲区长度,截断消息返回;否则,不接受该消息,出错返回

返回值:

  • 调用成功,返回实际读取到的消息的字节数
  • 调用失败,返回-1

msgctl()

函数原型:

#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds* buf);

参数说明:

  • msqid:消息队列的标识符
  • buf:指向msqid_ds结构的指针
  • cmd:控制命令
    • IPC_RMID删除消息队列
    • IPC_STAT获取消息队列的msqid_ds结构,保存于buf所指向的缓冲区
    • IPC_SET设置消息队列的msqid_ds结构,按照buf指向的结构的值

返回值:

  • 调用成功,返回0
  • 调用失败,返回-1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

golemon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值