Linux ipc通信(消息对列)

本文详细介绍了Linux系统中的消息队列机制,包括创建消息队列、消息发送(msgsnd)与接收(msgrcv)、msgctl系统调用以及msqid_ds结构的管理。

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

前言:消息队列也是linux开发ipc机制中较为重要的一个进程间通信机制。

1.系统创建或获取消息对列
int msgget(key_t key, int mode);

创建消息队列,或者获取消息队列。
参数:
key - 使用ftok()获取到的key
mode - IPC_CREAT|0666
返回:
消息队列的ID

2.往队列里发送一条消息。此操作被中断后不会被重启(信号处理中SA_RESTART)

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

参数:
msgid: - 消息队列的id
msgp - 消息,通常为下面的结构体
struct msgbuf{
long mtype; /消息类型,必需>0/
char mtext[100]; /消息数据,可自定义类型与大小/
};
msgsz - 消息的长度,指的消息数据的长度
msgflg - IPC_NOWAIT(不阻塞),MSG_EXCEPT(接受不检测mtype),MSG_NOERROR(消息数据过长时会截断数据)
返回:
0表示成功, -1表示失败

*3.int msgrcv(int msgid, void msgp, int msgsz, long msgtyp, int msgflg);

作用:接收消息队列中的消息

所需要的头文件:
#include <sys/types>
#include <sys/ipc.h>
#include <sys/msg.h>

在这里插入图片描述
*4.int msgctl(int msqid, int cmd, struct msqid_ds buf)

作用:msgctl系统调用对msqid标识的消息队列执行cmd命令操作。

返回值:0,成功;-1,失败;EFAULT(buf指向的地址无效);EIDRM(在读取中队列被删除);EINVAL(msgqid无效,或者msgsz小于0);EPERM(IPC_SET或者IPC_RMID命令被使用,但调用程序没有写的权限)

使用命令:
IPC_STAT:读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中。

IPC_SET:设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数。

IPC_RMID:从系统内核中移走消息队列。

我们再说一下队列的msqid_ds结构体,对于每一个队列都有一个msqid_ds来描述队列当前的状态
struct msqid_ds {//Linux系统中的定义
struct ipc_perm msg_perm; /* Ownership and permissions
time_t msg_stime; /* Time of last msgsnd() /
time_t msg_rtime; /
Time of last msgrcv() /
time_t msg_ctime; /
Time of last change /
unsigned long __msg_cbytes; /
Current number of bytes inqueue (non-standard) /
msgqnum_t msg_qnum; /
Current number of messagesin queue /
msglen_t msg_qbytes; /
Maximum number of bytesallowed in queue /
pid_t msg_lspid; /
PID of last msgsnd() /
pid_t msg_lrpid; /
PID of last msgrcv() */
};//不同的系统中此结构会有不同的新成员。这个结构体的作用是用来管理消息队列的,通过cmd指令来设置这结构体中的值,进而达到控制消息队列的目的

### Linux IPC 进程间通信机制 #### 一、消息Linux环境中,当遇到异常工作模式下的通信需求时,例如通过`Ctrl+C`发送中断信号给正在运行的进程,这种情况下传递的信息属于唯一的一种异步通讯方式——消息[^1]。消息允许一个或多个进程向其中放置消息,并由其他进程读取消息而无需关心对方的存在与否。 #### 二、共享内存 为了提高多进程间的通信效率,在Linux下可以利用共享内存来完成这一目标。这里提到的关键概念是:多个进程只需共用一块共享内存即可;这块共享内存在创建之初并不隶属于任何一个特定进程,而是作为一个独立实体存在于系统之中。要使不同进程能访问这段共享内存,则需将其映射至各自行为空间的相应位置上形成所谓的“内存映射区”。具体来说,这涉及到将同一块物理地址加入到各个参与通信的进程各自的虚拟地址空间里去的操作,此过程可通过调用`shmat()`函数实现[^2][^4]。 #### 三、进程控制 除了上述两种常见的IPC手段外,还有一种特殊的场景涉及到了更深层次的过程交互形式—即某个进程试图全面掌控另一些进程的行为流程(比如调试器对被测程序)。在这种情形之下,前者往往期望能够捕捉后者产生的任何陷阱事件或是异常状况并即时获取其最新动态变化情况。这类高级别的跨进程管理功能同样构成了Linux操作系统所提供的丰富IPC特性的一部分[^3]。 ```c #include <sys/ipc.h> #include <sys/shm.h> int main(){ key_t key = ftok("testfile",65); int shmid = shmget(key,1024,0666|IPC_CREAT); // 创建/获得共享内存ID char *str=(char*) shmat(shmid,(void*)0,0); // 将共享内存连接到当前进程 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值