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

Linux共享内存原理及系统调用分析


shmget 是 System V 共享内存的核心系统调用之一,其权限位(shmflg 参数)决定了共享内存段的访问控制和创建行为。以下是权限位的详细解析:


权限位的组成

shmflg 参数由两部分组成:

  1. 权限标志(低 9 位):控制用户/组/其他进程的访问权限,格式与文件权限一致(八进制表示)。
  2. 创建标志(高 位):控制共享内存段的创建行为(如 IPC_CREAT)。

1. 权限标志(八进制格式)

权限位使用 9 位二进制 表示三类用户的权限:

  • 用户(Owner)权限:前 3 位(八进制的百位)。
  • 组(Group)权限:中间 3 位(八进制的十位)。
  • 其他(Others)权限:后 3 位(八进制的个位)。
权限位的含义
二进制位八进制值含义
04004用户可读
02002用户可写
01001用户可执行(通常忽略)
004040组可读
002020组可写
001010组可执行(通常忽略)
00044其他用户可读
00022其他用户可写
00011其他用户可执行(通常忽略)
常用权限示例
  • 0600:用户可读写,组和其他用户无权限。
  • 0644:用户可读写,组和其他用户只读。
  • 0666:所有用户可读写(需谨慎使用)。

2. 创建标志

通过按位或(|)组合以下标志,控制共享内存的创建行为:

标志值(十六进制)作用
IPC_CREAT0x200如果共享内存不存在,则创建;否则直接返回现有段的标识符。
IPC_EXCL0x400IPC_CREAT 联用,若共享内存已存在,则返回错误(errno = EEXIST)。
IPC_NOWAIT0x800非阻塞模式,若操作需等待(如资源不足),立即返回错误(较少使用)。

3. 权限检查规则

  • 创建共享内存段时
    shmflg 的权限位会写入共享内存段的 shm_perm.mode 字段,后续进程访问时需匹配这些权限。
  • 访问现有段时
    内核会检查进程的 有效用户 ID有效组 ID 是否符合权限:
    1. 若进程的 EUID 与段的所有者 EUID 相同,检查 用户权限位
    2. 若进程的 EGID 与段的组 EGID 相同,检查 组权限位
    3. 否则检查 其他用户权限位

4. 示例代码

#include <sys/ipc.h>
#include <sys/shm.h>int main() {key_t key = ftok("/tmp/shm_example", 'A');  // 生成唯一键值// 创建共享内存段:用户可读写,组和其他用户只读int shmid = shmget(key, 4096, IPC_CREAT | 0644);if (shmid == -1) {perror("shmget failed");return 1;}// 其他操作(shmat、读写数据等)...return 0;
}

5. 常见问题与错误

权限不足(EACCES
  • 原因:进程没有权限访问现有共享内存段。
  • 解决方案
    1. 检查权限位是否允许当前用户/组访问。
    2. 以 root 权限运行进程(不推荐,存在安全风险)。
    3. 修改现有段的权限(需拥有者或 root 权限):
      struct shmid_ds shm_info;
      shmctl(shmid, IPC_STAT, &shm_info);
      shm_info.shm_perm.mode = 0666;  // 开放所有用户读写
      shmctl(shmid, IPC_SET, &shm_info);
      
段已存在(EEXIST
  • 原因:使用了 IPC_CREAT | IPC_EXCL,但共享内存已存在。
  • 解决方案:删除旧段或调整键值(key)。

6. 总结

  • 权限位:定义共享内存段的访问规则,格式与文件权限一致(如 0644)。
  • 创建标志IPC_CREAT 创建新段,IPC_EXCL 确保唯一性。
  • 权限检查:基于进程的 EUID/EGID 和权限位匹配。

合理设置权限位是保证共享内存安全性和功能性的关键!

http://www.dtcms.com/a/233709.html

相关文章:

  • Linux 内核队列调度相关内核选项详解
  • 用ApiFox MCP一键生成接口文档,做接口测试
  • 十八、【用户认证篇】安全第一步:基于 JWT 的前后端分离认证方案
  • 浅谈控制器
  • Redis:介绍和认识,通用命令,数据类型和内部编码,单线程模型
  • Hive中ORC存储格式的优化方法
  • 11 - ArcGIS For JavaScript -- 高程分析
  • day38 6月5号
  • golang 如何定义一种能够与自身类型值进行比较的Interface
  • ignore文件不生效的问题
  • JVM垃圾回收器-ZGC
  • 【赵渝强老师】Docker的图形化管理工具
  • 行内样式:深入解析与应用指南
  • SpringCloud——OpenFeign
  • 大模型的开发应用(七):大模型的分布式训练
  • AtCoder-abc408_b 解析
  • snprintf函数用法及注意事项详解
  • 【鸿蒙在 ETS (Extendable TypeScript) 中创建多级目录或文件,可以使用鸿蒙的文件系统 API】
  • 力扣刷题Day 71:搜索旋转排序数组(33)
  • Win10、Win11系统,使用谷歌浏览器文件流下载,C盘剩余容量小于4GB时,下载失败问题
  • 我的创作纪念日——聊聊我想成为一个创作者的动机
  • 25.6.5学习总结
  • 风机下引线断点检测算法实现
  • 系统思考持续训练
  • 【Redis】笔记|第10节|京东HotKey实现多级缓存架构
  • 简化复杂系统的优雅之道:深入解析 Java 外观模式
  • AI大模型在测试领域应用案例拆解:AI赋能的软件测试效能跃迁的四大核心引擎(顺丰科技)
  • Q: 数据库增删改查的逻辑如何实现?
  • 软件测试基础知识总结
  • 08_10小结