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

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.lryc.cn/news/2401676.html

相关文章:

  • Jenkins | Linux环境部署Jenkins与部署java项目
  • react私有样式处理
  • UDP/TCP协议全解
  • nginx 服务启动失败问题记录
  • Duix.HeyGem:以“离线+开源”重构数字人创作生态
  • ubuntu22.04安装megaton
  • 风机下引线断点检测算法实现
  • Windows应用-GUID工具
  • vue+element-ui一个页面有多个子组件组成。子组件里面有各种表单,实现点击enter实现跳转到下一个表单元素的功能。
  • Spring Boot 启动流程及配置类解析原理
  • Vehicle HAL(5)--vhal 实现设置属性的流程
  • WebRTC中的几个Rtp*Sender
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素、栈与队列总结
  • Java编程课(一)
  • IDEA202403 设置主题和护眼色
  • 无人机螺旋桨平衡方法详解
  • VUE混合开发用哪个PHP框架好?
  • 基于51单片机的车内防窒息检测报警系统
  • Flask-Babel 使用示例
  • Android 轻松实现 增强版灵活的 滑动式表格视图
  • 寄存器模型生成:从手工到自动化
  • 国标GB28181视频平台EasyGBS视频实时监控系统打造换热站全景可视化管理方案
  • docker生命周期
  • 鸿蒙缺少WMIC missing WMIC
  • 25.6.5学习总结
  • Spring Boot 使用 SLF4J 实现控制台输出与分类日志文件管理
  • linux_centos7.x的ifconfig命令显示内容详解
  • CentOS 7 如何pip3安装pyaudio?
  • 6.5本日总结
  • 【个人笔记】数据库原理(西电)