linux消息队列函数

msgget

创建消息队列。如果把消息队列看做一个文件的话,那么该函数就相当于open

函数原型

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

参数

第一个参数是key值。

第二个参数的地位用来确定消息队列的访问权限。可以附加参数:

  • IPC_CREAT //如果key不存在,则创建*(类似open函数的O_CREAT)*
  • IPC_EXCL //如果key存在,则返回失败*(类似open函数的O_EXCL)*
  • IPC_NOWAIT //如果需要等待,则直接返回错误

比如:msgid=msgget(key,0666|IPC_CREAT)

返回值

成功执行时,返回消息队列标识符。失败返回-1,errno被设为以下的某个值

  • EACCES:指定的消息队列已存在,但调用进程没有权限访问它,而且不拥有CAP_IPC_OWNER权能
  • EEXIST:key指定的消息队列已存在,而msgflg中同时指定IPC_CREAT和IPC_EXCL标志
  • ENOENT:key指定的消息队列不存在同时msgflg中不指定IPC_CREAT标志
  • ENOMEM:需要建立消息队列,但内存不足
  • ENOSPC:需要建立消息队列,但已达到系统的限制

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.h中定义):
    • #define IPC_RMID 0
    • #define IPC_SET 1
    • #define IPC_STAT 2
    • #define IPC_INFO 3
  • buf

cmd字段除了公共的四个操作以外,还有自己独立的操作

  • IPC_RMID

删除消息队列。从系统中删除给消息队列以及仍在该队列上的所有数据,这种删除立即生效。
仍在使用这一消息队列的其他进程在它们下一次试图对此队列进行操作时,将出错,并返回EIDRM
此命令只能由如下两种进程执行:

  • 其有效用户ID等于msg_perm.cuid或msg_perm.guid的进程。

  • 另一种是具有超级用户特权的进程。

  • IPC_SET

设置消息队列的属性。按照buf指向的结构中的值,来设置此队列的msqid_id结构。
该命令的执行特权与上一个相同。

  • IPC_STAT

读取消息队列的属性。取得此队列的msqid_ds结构,并存放在**buf***中。

  • IPC_INFO

读取消息队列基本情况。

返回值

成功:IPC_STAT, IPC_SET, and IPC_RMID 返回0

失败:返回-1,并设置 errno

msgrcv msgsnd

这是一对函数,用于消息队列的发送和接收

描述

msgsnd函数用于将新的消息添加到消息队列的尾端。

msgrcv函数用于从消息队列中读取msqid指定的消息

函数原型

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
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);

参数

msgsnd
  • msqid:消息队列标识符(由msgget生成)
  • msgp:指向用户自定义的缓冲区(msgp)
  • msgsz:接收信息的大小。范围在0~系统对消息队列的限制值
  • msgflg:指定在达到系统为消息队列限定的界限时应采取的操作。
    • IPC_NOWAIT 如果需要等待,则不发送消息并且调用进程立即返回,errno为EAGAIN
    • 如果设置为0,则调用进程挂起执行,直到达到系统所规定的最大值为止,并发送消息
msgrcv
  • msqid:消息队列标识符

  • msgp:指向用户自定义的缓冲区(msgp)

  • msgsz:如果收到的消息大于msgsz,并且msgflg&MSG_NOERROR为真,则将该消息截至msgsz字节,并且不发送截断提示

  • msgtyp:用于指定请求的消息类型:

    • msgtyp=0:收到的第一条消息,任意类型。
    • msgtyp>0:收到的第一条msgtyp类型的消息。
    • msgtyp<0:收到的第一条最低类型(小于或等于msgtyp的绝对值)的消息。
  • msgflg:用于指定所需类型的消息不再队列上时的将要采取的操作:

IPC_NOWAIT:如果队列中没有符合条件的消息,则立即返回,而不是阻塞等待消息到达。如果同时设置了这个标志和消息队列中无消息符合接收条件,则 msgrcv 函数会返回 -1 并设置 errnoENOMSG

MSG_NOERROR:如果消息长度大于 msgsz,则截断消息,而不是返回错误。

MSG_EXCEPT:接收队列中除了 msgtyp 指定类型的消息之外的其他消息。

MSG_WAIT:如果没有消息可接收,则阻塞等待,直到有消息到达。

返回值

毋庸置疑,成功0,失败-1。
其他要注意的是,消息队列数据结构(msqid_ds类型)成员的变化:

msgsnd

成功时:

  • msg_qnum 以1为增量递增
  • msg_lspid 设置为调用进程的pid
  • msg_stime 设置为当前时间。
msgrcv

成功时:

  • msg_qnum 以1为增量递减
  • msg_lrpid 设置为调用进程的pid
  • msg_rtime 设置为当前时间。

msgp

该类型需要自己在编程时定义,用于存储消息的内容。
下面给出一个范例,注意,里面的名称随意。

struct msgbuf{
    long mtype;   //消息类型
    char mtext[1];//数组大小编程时自己指定
};
  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux消息队列是一种进程间通信(IPC)方式之一。它是一个简单的消息传递机制,用于在进程之间传递数据。消息队列是一种先进先出(FIFO)的数据结构,它允许一个进程向队列中添加消息,另一个进程从队列中读取消息。 Linux消息队列由三部分组成: 1. 消息队列标识符:它是一个整数,用于标识消息队列。 2. 消息结构体:它包含要传递的数据和数据的长度。 3. 操作函数:用于创建、读取、写入和删除消息队列Linux消息队列的操作函数主要有以下几个: 1. msgget():创建或打开一个消息队列。 2. msgsnd():向消息队列中添加消息。 3. msgrcv():从消息队列中读取消息。 4. msgctl():控制和删除消息队列。 使用Linux消息队列的步骤如下: 1. 使用msgget()函数创建或打开一个消息队列,并获取消息队列标识符。 2. 使用msgsnd()函数消息队列中添加消息。 3. 使用msgrcv()函数消息队列中读取消息。 4. 使用msgctl()函数控制和删除消息队列Linux消息队列的优点是可以实现进程之间的异步通信,不需要像管道和FIFO一样进行同步。同时,消息队列可以缓存消息,当一个进程没有准备好读取消息时,消息不会被丢失。但是,Linux消息队列的缺点是如果发送者发送的消息大小超过了消息队列的大小,消息将被截断。此外,消息队列的使用会占用一定的系统资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值