进程间通信——消息队列(Message queue)

本文详细介绍了Linux系统中的消息队列,包括它的产生原因、定义、上限、数据结构、相关函数接口(msgget, msgsnd, msgrcv, msgctl)以及key_t键和ftok函数的使用。消息队列作为一种进程间通信机制,克服了管道的限制,提供了有序、可选的消息传递,具有生命周期长和灵活性高等优点。" 81701968,7364572,Java Socket连接与读取超时设置,"['Java网络编程', 'Socket编程', 'TCP连接', '异常处理']

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

Linux中,IPC消息队列是一个双向通信的全内存设计,即内核保证了读写顺序和数据同步,并且是性能比较好的先进先出的数据结构。消息队列的应用场景:比如异步任务处理,抢占式的数据分发,顺序缓存区等。

消息队列的产生原因

消息队列其实就是消息传输过程中保存消息的容器,既然有了管道,为什么要出现消息队列呢?理由如下:

(1)生命周期:匿名管道和命名管道都是随进程的,意味着管道的生命周期是随进程的退出而退出的。

(2)传送方式:管道传送数据时以无格式字节流的形式传送,给程序的开发带来不便。

(3)信号传递量:担当数据传送媒介的管道,其缓冲区大小受到较大的限制。

鉴于上面的三种原因:IPC方式下的另一种进程间通信——>消息队列应运而生。它克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

什么是消息队列?

[普通定义]:消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法,每个数据块都被认为含有一个类型,接受者接受的数据块可以有不同的类型值,我们可以通过发送消息来避免命名管道的同步和阻塞问题。

[最佳定义]:内核地址空间中的内部链表,消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取,每个消息队列是由IPC标识符所唯一标识的。

消息队列与管道的不同在于:消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出,而且如果你没有显示的删除它,那么在关机之前它一直存在。

消息队列的上限

消息队列与管道也是一样的不足,就是每个消息队列的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限(MSGMNB),系统上消息队列的总数也是有一个上限(MSGMNI)。

[root@localhost panpan]# cat /proc/sys/kernel/msgmax
65536   //每个消息的最大长度
[root@localhost panpan]# cat /proc/sys/kernel/msgmnb
65536   //每个消息队列的总的字节数
[root@localhost panpan]# cat /proc/sys/kernel/msgmni
1735   //系统消息队列的总数

IPC对象数据结构

内核为每个IPC对象维护了一个数据结构(存在于/usr/include/linux/ipc.h

struct ipc_perm
{
        __kernel_key_t  key;//端口号
        __kernel_uid_t  uid;//所有者的用户ID
        __kernel_gid_t  gid;//所有者组ID
        __kernel_uid_t  cuid;//创建者的用户ID
        __kernel_gid_t  cgid;//创建者的组ID
        __kernel_mode_t mode; //访问模式
        unsigned short  seq;//顺序值
};

不仅如此,消息队列,共享内存和信号量都有这样一个共同的数据结构。

消息队列结构

消息队列结构存在于/usr/include/linux/msg.h目录下:

struct msqid_ds {
        struct ipc_perm msg_perm;    /* IPC对象结构体 */
        struct msg *msg_first;       /*消息队列头指针*/
        struct msg *msg_last;        /*消息队列尾指针*/
        __kernel_time_t msg_stime;   /*最后一次插入消息队列消息的时间*/
        __kernel_time_t msg_rtime;   /*最后一次接收消息即删除队列中一个消息的时间*/
        __kernel_time_t msg_ctime;   /* 最后修改队列的时间*/
        unsigned long  msg_lcbytes;  /* Reuse junk fields for 32 bit */
        unsigned long  msg_lqbytes;  /* ditto */
        unsigned short msg_cbytes;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值