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

Linux系统--进程间通信--共享内存相关指令

Linux系统–进程间通信–共享内存相关指令

核心概念回顾:

  • 共享内存: 允许多个进程访问同一块物理内存区域,是进程间通信(IPC)中最快的方式之一,因为它避免了内核空间和用户空间之间的数据复制。
  • System V IPC: Linux 继承了 Unix System V 的 IPC 机制,包括共享内存、消息队列和信号量。这些 IPC 对象由内核管理,并通过唯一的标识符(keyshmid)访问。
  • key(ftok): 一个整数值,通常由 ftok()函数根据文件路径和项目 ID 生成,用于在进程间约定访问同一个 IPC 对象。
  • shmid: 共享内存标识符。当进程成功创建或连接到共享内存段后,内核返回此 ID。后续操作(如附加、分离、控制)通常使用此 ID。
  • 权限 (shm_perm): 定义了共享内存段的访问权限(属主、属组、其他用户的读/写权限)和属主/属组信息。

主要相关命令:

Linux 没有专门为共享内存设计的单一“创建”或“附加”命令(这些操作通常在 C/C++ 程序中使用 shmget(), shmat(), shmdt(), shmctl()系统调用完成)。管理共享内存的主要工具是查看和删除 IPC 对象的通用命令:

  1. ipcs(IPC Status)
  2. ipcrm(IPC Remove)

此外,了解 /proc文件系统下的接口也很重要:

  1. /proc/sysvipc/shm

详细讲解每个命令:


1. ipcs- 查看 IPC 状态

  • 作用: 显示当前系统中存在的 System V IPC 对象的信息,包括共享内存(Shared Memory)、消息队列(Message Queues)和信号量(Semaphore)。它是查看共享内存状态的主要工具。

  • 语法:

    ipcs [options]
    
  • 常用命令行参数 (针对共享内存):

    • -m--shm-mems 只显示共享内存段的信息。(最常用)
    • -i <shmid>--id <shmid> 显示指定 ID (shmid) 的共享内存段的详细信息。
    • -l--limits 显示系统对 IPC 资源的限制(如最大共享内存段大小、最大段数等)。
    • -p--pid 显示创建者和最后操作者的进程 ID (PID)。
    • -t--time 显示附加时间 (attached-time)、分离时间 (detached-time) 和变更时间 (changed-time)。时间格式可以用 -u指定为秒。
    • -c--creator 显示创建者信息(用户和组)。
    • -b--bytes 以字节为单位显示大小(默认单位可能因系统而异,通常是 KB)。
    • -u--summary 显示 IPC 资源使用的摘要信息。
    • -a--all 显示所有信息(相当于 -m -q -s -c -l -u -p -t)。输出可能很长。
    • --human 以人类可读的格式显示大小(例如,K, M, G)。
  • 输出字段解释 (使用 ipcs -m时):

    • key 共享内存段的键值 (ftok生成或 IPC_PRIVATE)。
    • shmid 共享内存段的唯一标识符。
    • owner 共享内存段的所有者。
    • perms 访问权限(八进制表示,如 666)。
    • bytes 共享内存段的大小(单位受 -b参数影响)。
    • nattch 当前附加(连接)到该共享内存段的进程数量。
    • status 状态标志(如 dest表示该段已被标记为待销毁,当 nattch为 0 时会被内核删除)。
    • attached-time, detached-time, changed-time 时间信息(需要 -t参数)。
    • creator-uid, creator-gid, cuid, cgid 创建者和所有者的 UID/GID(需要 -c参数)。
    • lpid, cpid 最后操作该段的进程 PID (lpid) 和创建该段的进程 PID (cpid)(需要 -p参数)。
  • 使用示例:

    • 查看所有共享内存段:

      $ ipcs -m
      ------ Shared Memory Segments --------
      key        shmid      owner      perms      bytes      nattch     status
      0x00000000 32768      user       600        524288     2          dest
      0x0000abcd 65537      user       666        1024       1
      
    • 查看指定 shmid的详细信息:

      $ ipcs -m -i 65537
      Shared memory Segment shmid=65537
      uid=1000    gid=1000    cuid=1000    cgid=1000
      mode=0666   access_perms=0666
      bytes=1024  lpid=1234   cpid=5678    nattch=1
      att_time=Sat Oct 12 11:15:30 2025
      det_time=Sat Oct 12 11:15:30 2025
      change_time=Sat Oct 12 11:15:30 2025
      
    • 查看共享内存系统限制:

      $ ipcs -m -l
      ------ Shared Memory Limits --------
      max number of segments = 4096
      max seg size (kbytes) = 18014398509465599
      max total shared memory (kbytes) = 18014398509481980
      min seg size (bytes) = 1
      
    • 查看共享内存段并显示创建者和最后操作者的 PID:

      $ ipcs -m -p
      ------ Shared Memory Segments --------
      key        shmid      owner      perms      bytes      nattch     cpid      lpid
      0x00000000 32768      user       600        524288     2          7890      1234
      0x0000abcd 65537      user       666        1024       1          5678      5678
      
    • 查看共享内存段摘要:

      $ ipcs -m -u
      ------ Shared Memory Status --------
      segments allocated 2
      pages allocated 513 (524288 bytes)
      pages resident  513
      pages swapped   0
      Swap performance: 0 attempts, 0 successes
      
  • 注意事项:

    • 需要足够的权限才能查看不属于当前用户的共享内存段信息(通常是 root 或目标段的所有者)。
    • 理解输出字段的含义对于诊断问题至关重要(如 nattch, status, lpid)。
    • key0x00000000通常是使用 IPC_PRIVATE创建的段。

2. ipcrm- 删除 IPC 对象

  • 作用: 删除指定的 System V IPC 对象,包括共享内存段、消息队列和信号量集。它是移除不再需要的共享内存段的主要命令行工具。

  • 语法:

    ipcrm [options]
    
  • 常用命令行参数 (针对共享内存):

    • -m <shmid>--shmemid <shmid> 删除指定 shmid的共享内存段。
    • -M <shmkey>--shmemkey <shmkey> 删除具有指定 key的共享内存段。<shmkey>可以是 ipcs -m输出的 key列的数值(通常是十六进制,但这里需要十进制表示!)或十六进制(以 0x开头)。
    • -a--all [shm|msg|sem] 删除当前用户拥有的所有 IPC 对象。可以指定类型(shm, msg, sem),如果不指定则删除所有三种类型。(非常危险!)
    • -Q <msgkey>, -q <msgid>, -S <semkey>, -s <semid> 用于删除消息队列和信号量(与共享内存无关)。
  • 使用示例:

    • 通过 shmid删除共享内存段:

      $ ipcs -m  # 先查看,假设要删除 shmid=65537
      $ ipcrm -m 65537
      
    • 通过 key删除共享内存段:

      • 假设 ipcs -m显示 key0x0000abcd
      • 需要将十六进制 0x0000abcd转换为十进制 43981,或者直接使用十六进制格式(带 0x):
      $ ipcrm -M 0x0000abcd  # 推荐:直接使用十六进制 key
      # 或者
      $ ipcrm -M 43981       # 使用十进制表示(43981 是 0xabcd 的十进制)
      
    • 删除当前用户创建的所有共享内存段: (谨慎使用!)

      $ ipcrm -a shm
      
  • 注意事项:

    • 极其危险: ipcrm会直接删除内核中的 IPC 对象。如果仍有进程附加(nattch > 0)到该共享内存段,删除操作会立即将该段标记为销毁(status显示 dest)。一旦所有进程都分离(nattch变为 0),内核会立即销毁该段及其内容。 这会导致仍在使用该段的进程出现错误(如 SIGSEGV段错误)或读取到无效数据。
    • 权限: 通常只有 root 用户或共享内存段的创建者(所有者)才能删除它。
    • key的表示: 使用 -M参数时,<shmkey>可以是十进制数字或十六进制(以 0x开头)。ipcs默认输出十六进制 key,直接复制到 ipcrm -M 0x...最方便。
    • -a的危险性: ipcrm -aipcrm -a shm会删除当前用户创建的所有共享内存段。如果该用户运行了多个使用共享内存的服务,这个命令会同时破坏所有这些服务。在生产环境中绝对禁止随意使用! 务必先用 ipcs -m确认要删除的对象。
    • 孤儿对象: 如果创建共享内存段的进程异常终止(没有调用 shmctl(..., IPC_RMID, ...)),共享内存段会变成“孤儿”,一直存在直到被手动删除或系统重启。ipcrm是清理这些孤儿对象的主要方法。
    • 系统重启: 系统重启会清除所有 IPC 对象(包括共享内存)。

3. /proc/sysvipc/shm- 通过 proc 文件系统查看共享内存

  • 作用: 这不是一个命令,而是 Linux /proc虚拟文件系统提供的一个文件。读取该文件的内容可以获取当前系统中所有 System V 共享内存段的详细信息,格式比 ipcs更原始但也更全面。

  • 使用方法: 使用文本查看命令(如 cat, less, more)读取该文件。

    $ cat /proc/sysvipc/shm
    
  • 输出字段解释: 输出是一个表格,每行代表一个共享内存段,字段以空格分隔。字段顺序通常是:

    • shmid: 共享内存段 ID。
    • key: 键值(十进制)。
    • shmid: (再次出现,有时是 shmseg,含义相同)。
    • perms: 权限(八进制)。
    • size: 大小(字节)。
    • cpid: 创建者 PID。
    • lpid: 最后操作(shmat/shmdt)的进程 PID。
    • nattch: 当前附加的进程数。
    • uid: 所有者 UID。
    • gid: 所有者 GID。
    • cuid: 创建者 UID。
    • cgid: 创建者 GID。
    • atime: 最后附加时间(自 1970-01-01 00:00:00 UTC 起的秒数)。
    • dtime: 最后分离时间(自 1970-01-01 00:00:00 UTC 起的秒数,0 表示未分离)。
    • ctime: 最后变更时间(权限、所有者等变更,自 1970-01-01 00:00:00 UTC 起的秒数)。
    • rss: 驻留集大小(实际在物理内存中的部分,字节)。
    • swap: 被交换到磁盘的大小(字节)。
  • 使用示例:

    $ cat /proc/sysvipc/shm
    65537 43981 65537 666 1024 5678 1234 1 1000 1000 1000 1000 1697091330 0 1697091330 1024 0
    32768 0 32768 600 524288 7890 1234 2 1000 1000 1000 1000 1697091200 0 1697091200 524288 0
    

    (需要根据上面的字段顺序自行解析)

  • 注意事项:

    • 输出是原始数据,没有表头,需要对照字段顺序理解。
    • 时间戳是 epoch 时间(秒数),需要转换才能理解。
    • 提供的信息比 ipcs更底层和详细(如 rss, swap)。
    • 主要用于脚本解析或需要非常详细信息的情况。日常管理使用 ipcs更直观方便。
    • 需要读取权限(通常 /proc下的文件对所有用户可读)。

总结与重要注意事项:

  1. 核心命令: ipcs(查看) 和 ipcrm(删除) 是管理共享内存的主要命令行工具。/proc/sysvipc/shm提供底层信息。
  2. 创建与附加: 共享内存段的创建 (shmget) 和附加 (shmat) 通常在应用程序内部(C/C++等)使用系统调用完成,没有直接对应的命令行工具。命令行主要用于管理和监控。
  3. 删除的危险性: ipcrm是极其危险的操作。 务必先用 ipcs -m确认目标共享内存段,确保没有关键进程(nattch应为 0 或确认可以安全中断)在使用它。误删会导致进程崩溃或数据丢失。生产环境操作务必谨慎!
  4. 权限: 查看和删除共享内存段通常需要 root 权限或你是该段的所有者。
  5. 孤儿对象: 程序崩溃可能导致共享内存段残留。定期使用 ipcs -m检查并使用 ipcrm清理不再使用的段是良好的系统管理实践。
  6. 系统限制: 了解系统对共享内存的限制 (ipcs -m -l) 对于设计和调试使用共享内存的应用程序很重要。
  7. key的转换: 使用 ipcrm -M时,注意 ipcs输出的 key是十六进制,而 ipcrm -M接受十六进制(带 0x)或十进制。使用十六进制格式 0x...最不容易出错。
  8. 替代方案: POSIX 共享内存 (shm_open, mmap) 是现代 Linux 上另一种共享内存机制,通常通过挂载在 /dev/shm下的文件进行操作(使用 ls, rm等普通文件命令管理)。本文主要讲解传统的 System V 共享内存。
http://www.dtcms.com/a/473398.html

相关文章:

  • 网站开发的实践报告石家庄市工程勘察设计咨询业协会
  • TensorFlow深度学习实战——图分类
  • SAP MM采购信息记录维护接口分享
  • 网站搭建装修风格大全2021新款简约
  • Mysql初阶第八讲:Mysql表的内外连接
  • SpringCloud 入门 - Gateway 网关与 OpenFeign 服务调用
  • uniapp 选择城市(城市列表选择)
  • AR小白入门指南:从零开始开发增强现实应用
  • 02_k8s资源清单
  • 2025年渗透测试面试题总结-109(题目+回答)
  • uniapp配置自动导入uni生命周期等方法
  • flink的Standalone-HA模式安装
  • Flink时态表关联:实现数据“时间旅行”的终极方案
  • 做哪类英文网站赚钱wordpress 页面 列表
  • nginx + spring cloud + redis + mysql + ELFK 部署
  • 【黑马点评 - 实战篇01】Redis项目实战(Windows安装Redis6.2.6 + 发送验证码 + 短信验证码登录注册 + 拦截器链 - 登录校验)
  • 汕头市通信建设管理局网站二网站手
  • FreeRTOS小记
  • 数据结构实战:顺序表全解析 - 从零实现到性能分析
  • 【C++进阶】继承上 概念及其定义 赋值兼容转换 子类默认成员函数的详解分析
  • 华为matebook16s 2022禁用触摸板和触摸屏操作
  • GridRow 和 Column 有啥区别
  • 030159网站建设与维护中国科技成就素材
  • Echarts 5.6.0 Grid 坐标系中 Y 轴可视化的优化之路
  • Java 线程池如何知道一个线程的任务已经执行完成
  • JVM字节码与类的加载(一):类的加载过程详解
  • 强军网网站建设网站需要备案才能建设吗
  • 耄大厨——AI厨师智能体(3-工具调用)
  • (二)黑马React(导航/账单项目)
  • SA-LSTM