当前位置: 首页 > news >正文

OS55.【Linux】System V消息队列的简单了解

目录

1.知识回顾: 进程间通信的前提

2.消息队列的原理

3.消息队列的系统调用

msgget

msgctl

msgsnd

查看消息队列的命令

删除消息队列的命令

4.shmid_ds、msqid_ds、semqid_ds共同点

有统一的结构

如何管理struct ipc_perm?


1.知识回顾: 进程间通信的前提

之前在前面的几篇文章都反复强调了进程间通信的前提:必须先让不同进程间看到同一份资源

,同一份资源可以是文件缓冲区也可以是内存块也可以是:对于System V消息队列,即必须先让不同进程间看到同一个队列,如下图:

2.消息队列的原理

进程间以数据块的形式发送数据,这些数据块需要排队形成队列

这个数据块是带类型的数据块

假设进程A和进程B使用消息队列进行通信,那么进程A和要区分是自己发送的数据块还是进程B发给它的

其次,该队列肯定由操作系统提供,不可能是进程提供的,因为进程间具有独立性

3.消息队列的系统调用

类比OS52.【Linux】System V 共享内存(1)文章讲的:shmget、shmat、shmdt、shmctl系统调用

msgget

作用: 获取或创建消息队列

和之前一样, key仍然用ftok算

若要创建全新的消息队列,则msgflg为IPC_CREAT | IPC_EXCL

返回值也和shmget类似:

注意: 消息队列的msgget和共享内存的shmget有区别,消息队列不用提供大小

msgctl

若要关闭消息队列,buf传空指针即可

msgsnd

msgsnd的snd是send的缩写,作用: 发送消息,换句话说,是发送数据块

msqid、msgflg分别类似shmid、shmflg

msgp指向要发送的数据块,msgsz为要发送数据块的大小

注意到: msgp的类型是const void*,用户可以自己定义类型进行传递

手册指出"caller-defined structure": 大致定义为struct msgbuf

查看消息队列的命令

ipcs -q

删除消息队列的命令

ipcrm -M key #或 ipcrm -m shmid

4.shmid_ds、msqid_ds、semqid_ds共同点

shmid_ds负责描述共享内存:

struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ time_t shm_atime; /* Last attach time */ time_t shm_dtime; /* Last detach time */ time_t shm_ctime; /* Creation time/time of last modification via shmctl() */ pid_t shm_cpid; /* PID of creator */ pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */ shmatt_t shm_nattch; /* No. of current attaches */ ... }; struct ipc_perm { key_t __key; /* Key supplied to shmget(2) */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions + SHM_DEST and SHM_LOCKED flags */ unsigned short __seq; /* Sequence number */ };

msqid_ds负责描述消息队列:

struct msqid_ds { struct ipc_perm msg_perm; /* Ownership and permissions */ time_t msg_stime; /* Time of last msgsnd(2) */ time_t msg_rtime; /* Time of last msgrcv(2) */ time_t msg_ctime; /* Time of creation or last modification by msgctl() */ unsigned long msg_cbytes; /* # of bytes in queue */ msgqnum_t msg_qnum; /* # number of messages in queue */ msglen_t msg_qbytes; /* Maximum # of bytes in queue */ pid_t msg_lspid; /* PID of last msgsnd(2) */ pid_t msg_lrpid; /* PID of last msgrcv(2) */ }; struct ipc_perm { key_t __key; /* Key supplied to msgget(2) */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions */ unsigned short __seq; /* Sequence number */ };

进程间通信其实还可以用信号量,semqid_ds负责描述信号量:

struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Creation time/time of last modification via semctl() */ unsigned long sem_nsems; /* No. of semaphores in set */ }; struct ipc_perm { key_t __key; /* Key supplied to semget(2) */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions */ unsigned short __seq; /* Sequence number */ };

有统一的结构

System V的进程间通信被精心设计过,三个结构体的第一个字段类型都是struct ipc_perm,尽管shm_perm msg_perm sem_perm的名字不一样

struct xxxid_ds { struct ipc_perm xxx_perm; /* Ownership and permissions */ //...... }; struct ipc_perm { key_t __key; uid_t uid; gid_t gid; uid_t cuid; gid_t cgid; unsigned short mode; unsigned short __seq; };

这里面有面向对象的思想,struct xxxid_ds含有struct ipc_perm xxx_perm,显然后者是基类,前者是子类

如何管理struct ipc_perm?

答:先描述再组织

先描述: ipc权限使用struct ipc_perm

再组织: 使用数据结构将struct ipc_perm串起来

描述ipc权限有两种,struct ipc_perm是用户层的描述,struct kern_ipc_perm是内核层的描述

例如linux 2.6.18内核的/include/linux/ipc.h定义了struct kern_ipc_perm:

/* used by in-kernel data structures */ struct kern_ipc_perm { spinlock_t lock; int deleted; key_t key; uid_t uid; gid_t gid; uid_t cuid; gid_t cgid; mode_t mode; unsigned long seq; void *security; };

/ipc/util.h中定义了struct ipc_id_ary ,其使用变长数组织ipc权限:

struct ipc_id_ary { int size; struct kern_ipc_perm *p[0]; //写在结构体末尾,是变长数组 };

将shm_perm、msg_perm、sem_perm的地址写入struct kern_ipc_perm *p[0],那么就能很方便地使用箭头->和强制类型转换访问struct shmid_ds msqid_ds semid_ds的每一个字段:

因为三个结构体的第一个字段类型都是struct ipc_perm,即struct ipc_perm字段的地址等同于struct xxxid_ds的地址

//addr1、addr2、addr3的类型都为struct ipc_perm* ((struct shmid_ds*)addr1)->??? ((struct msqid_ds*)addr2)->??? ((struct semqid_ds*)addr3)->???

管理ipc权限就相当于对struct kern_ipc_perm *p[0]进行增删改查

描述xxid有两种,struct xxxid_ds是用户层的描述,struct xxxid_kernel是内核层的描述

例如Linux 6.18.6中的/ipc/shm.c:

struct shmid_kernel /* private to the kernel */ { struct kern_ipc_perm shm_perm; struct file *shm_file; unsigned long shm_nattch; unsigned long shm_segsz; time64_t shm_atim; time64_t shm_dtim; time64_t shm_ctim; struct pid *shm_cprid; struct pid *shm_lprid; struct ucounts *mlock_ucounts; /* * The task created the shm object, for * task_lock(shp->shm_creator) */ struct task_struct *shm_creator; /* * List by creator. task_lock(->shm_creator) required for read/write. * If list_empty(), then the creator is dead already. */ struct list_head shm_clist; struct ipc_namespace *ns; } __randomize_layout;

补: shmid msqid semid是数组的下标,是线性递增的

http://www.jsqmd.com/news/318729/

相关文章:

  • 2026国内外主流大模型全景对比:技术演进与场景适配深度解析
  • 38-mini-vue 实现解析 element
  • Java零基础必看,1小时搞定微服务,从0到1搭建springcloud+nacos实战项目,搞定企业刚需技术!
  • 第6章:字符设备驱动的高级操作1:ioctl 系统调用
  • SQL 注入攻防进阶
  • 让 Q 值估计更准确:从 DQN 到 Double DQN 的改进方案
  • 《贾子智慧理论体系:从认知到文明的统一框架》| Kucius Wisdom Framework: A Unified Framework from Cognition to Civilization
  • 使用Dockerfile构建Flask应用镜像
  • vulnstack红队实战一
  • 全球首次突破异形框定位难题,百度开源全新OCR模型 PaddleOCR-VL-1.5
  • 智能指针详解
  • PVE 9.0 定制 Debian 13 镜像 支持 Cloud-Init 敏捷部署虚拟机【模板篇】
  • Java面试中的异常继承难题:自定义Exception避坑指南
  • Spring Boot的项目创建
  • 小程序毕设项目推荐-基于SpringBoot的医院设备管理及报修系统微信小程序基于springboot的医院设备管理及报修小程序的设计与实现【附源码+文档,调试定制服务】
  • 小程序毕设选题推荐:基于springboot的医院设备管理及报修小程序的设计与实现基于微信小程序的医院设备管理及报修系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 基于SpringBoot的房屋租售系统毕业论文+PPT(附源代码+演示视频)
  • 销售实战资源合集
  • 使用 NanUI 快速创建具有现代用户界面的 WinForm 应用程序
  • AI运维专家圆桌:新兴技术类别的诞生
  • ServiceNow与Anthropic达成多年合作协议
  • 一款基于 .NET Avalonia 开源免费、快速、跨平台的图片查看器
  • 【课程设计/毕业设计】基于微信小程序的医院设备管理及报修系统基于springboot的医院设备管理及报修小程序的设计与实现【附源码、数据库、万字文档】
  • AI工具存在严重安全脆弱性,治理刻不容缓
  • 小程序计算机毕设之基于SpringBoot+微信小程序的微信医院医疗设备管理系统管理系统基于springboot的医院设备管理及报修小程序的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • SolarWinds修复Web Help Desk四个关键漏洞
  • 小程序毕设项目:基于springboot的医院设备管理及报修小程序的设计与实现(源码+文档,讲解、调试运行,定制等)
  • 为啥大厂 FPS 进对局不立刻清空局外缓存,而是打完再清?(大白话超长版)
  • 【毕业设计】基于springboot的医院设备管理及报修小程序的设计与实现(源码+文档+远程调试,全bao定制等)
  • 大数据架构设计:非结构化数据处理系统搭建