System V 共享内存系统管理命令
本文档介绍用于查看和管理 System V 共享内存段的系统命令.
查看共享内存
查看所有共享内存段
ipcs -m输出示例:
------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 0 root 600 4096 0 0x12345678 32769 user 666 128 2字段说明:
key: 共享内存段的键值shmid: 共享内存标识符owner: 所有者perms: 权限bytes: 大小(字节)nattch: 当前附加的进程数status: 状态(见下方详细说明)
status 字段说明
status字段显示共享内存段的当前状态, 可能的值包括:
空(正常状态)
当status字段为空时, 表示共享内存段处于正常状态:
- 段未被标记为删除
- 可以正常使用
- 进程可以附加和分离
示例输出:
key shmid owner perms bytes nattch status 0x12345678 32769 user 666 128 2dest(删除标记)
当status字段显示dest时, 表示共享内存段已被标记为删除:
- 段已被调用
shmctl(IPC_RMID)或ipcrm -m标记为删除 - 但仍有进程附加到该段, 因此段尚未真正删除
- 新的进程不能再附加到该段
- 当所有进程都分离(
shmdt)后, 段才会被真正删除
示例输出:
key shmid owner perms bytes nattch status 0x12345678 32769 user 666 128 1 dest状态转换流程:
正常状态 → shmctl(IPC_RMID) → dest 状态 → 所有进程分离 → 真正删除注意事项:
dest状态是临时状态, 表示段正在等待所有进程分离- 如果看到
dest状态但nattch为 0, 可能是显示延迟, 段应该很快会被删除 - 处于
dest状态的段无法被新进程附加, 但已附加的进程仍可正常使用 - 如果程序异常退出未调用
shmdt(), 段可能一直处于dest状态, 需要手动清理
查看处于删除状态的共享内存段:
# 查看所有标记为删除的共享内存段ipcs -m|grepdest# 查看标记为删除且没有进程附加的段ipcs -m|awk'NR > 3 &&$7== "dest" &&$6== 0 {print$2}'查看特定共享内存段的详细信息
ipcs -m -i<shmid>例如:
ipcs -m -i32769查看系统限制
ipcs -l或者只查看共享内存的限制:
ipcs -l -m输出示例:
------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 18014398509481983 max total shared memory (kbytes) = 18014398509481983 min seg size (bytes) = 1删除共享内存
根据 shmid 删除
ipcrm -m<shmid>例如:
ipcrm -m32769根据键值删除
ipcrm -M<key>例如:
ipcrm -M 0x12345678注意:
- 删除共享内存段时, 如果仍有进程附加到该段, 段不会被立即删除, 而是标记为删除状态. 当所有进程都分离后, 段才会被真正删除.
- 使用
IPC_PRIVATE创建的共享内存段只能通过shmid删除, 因为键值为 0, 无法通过键值删除.
删除时机和注意事项
删除时机:
- 立即删除: 调用
shmctl(IPC_RMID)或ipcrm -m后, 共享内存段立即被标记为删除 - 真正删除: 当所有进程都调用
shmdt()分离后, 段才会被真正删除
注意事项:
- 进程仍在使用: 如果仍有进程附加到该段, 段不会被立即删除, 而是标记为删除状态(
dest) - 新进程无法附加: 标记为删除后, 新的进程不能再附加到该段
- 已附加进程: 已附加的进程仍可正常使用, 直到调用
shmdt()分离 - 异常退出: 如果进程异常退出未调用
shmdt(), 段可能一直处于dest状态, 需要手动清理 - 权限要求: 只有创建者、所有者或 root 用户可以删除共享内存段
删除状态检查
删除后可以检查状态确认:
# 查看是否标记为删除ipcs -m|grep<shmid># 如果显示 "dest" 状态, 说明已标记为删除, 等待进程分离# 如果不再显示, 说明已真正删除删除所有共享内存段(谨慎使用)
# 删除当前用户创建的所有共享内存段ipcs -m|awk'$3== ENVIRON["USER"] {print$2}'|xargs-I{}ipcrm -m{}或者使用 root 权限删除所有共享内存段:
ipcs -m|awk'NR > 3 {print$2}'|xargs-I{}ipcrm -m{}常用命令组合
查看并清理残留的共享内存段
# 查看所有共享内存段ipcs -m# 查看没有进程附加的共享内存段ipcs -m|awk'NR > 3 &&$6== 0 {print$2}'# 删除没有进程附加的共享内存段ipcs -m|awk'NR > 3 &&$6== 0 {print$2}'|xargs-I{}ipcrm -m{}查看特定用户的共享内存段
ipcs -m|grep<username>判断共享内存是否被进程附加
方法 1: 查看 nattch 字段
nattch字段显示当前附加到共享内存段的进程数:
ipcs -mnattch = 0: 没有进程附加, 共享内存段空闲nattch > 0: 有进程附加, 数值表示附加的进程数
示例:
key shmid owner perms bytes nattch status 0x12345678 32769 user 666 128 2表示有 2 个进程正在使用该共享内存段.
方法 2: 查看创建者和最后操作者 PID
使用-p选项查看创建者和最后操作者的进程 ID:
ipcs -m -p输出示例:
------ Shared Memory Segments -------- key shmid owner perms bytes nattch cpid lpid 0x12345678 32769 user 666 128 2 1234 5678字段说明:
cpid: 创建者进程 IDlpid: 最后操作者进程 ID(最后调用shmat或shmdt的进程)
注意:lpid是最后操作的进程, 不一定是当前附加的进程. 要确认进程是否仍在附加, 需要结合nattch字段.
方法 3: 使用 lsof 命令
lsof可以显示哪些进程打开了共享内存段:
# 查看所有使用共享内存的进程lsof|grepshm# 查看特定共享内存段的使用情况(需要知道段在 /dev/shm 中的文件名)# 注意: System V 共享内存通常不显示在 /dev/shm 中, 此方法主要用于 POSIX 共享内存方法 4: 查看 /proc/sysvipc/shm
直接查看内核提供的共享内存信息:
cat/proc/sysvipc/shm输出示例:
key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime 305419896 32769 666 128 1234 5678 2 1000 1000 1000 1000 1234567890 1234567890 1234567890字段说明:
key: 键值shmid: 共享内存标识符perms: 权限size: 大小(字节)cpid: 创建者进程 IDlpid: 最后操作者进程 IDnattch: 当前附加的进程数uid/gid: 所有者用户 ID/组 IDcuid/cgid: 创建者用户 ID/组 IDatime: 最后附加时间dtime: 最后分离时间ctime: 最后变更时间
方法 5: 使用 fuser 命令(不适用于 System V 共享内存)
fuser主要用于文件, System V 共享内存不适用此方法.
实用命令组合
查看所有正在使用的共享内存段
# 查看 nattch > 0 的共享内存段ipcs -m|awk'NR > 3 &&$6> 0'# 或者使用更详细的格式ipcs -m -p|awk'NR > 3 &&$6> 0'查看特定共享内存段的详细信息
# 查看特定 shmid 的详细信息ipcs -m -i<shmid># 查看特定 shmid 的创建者和最后操作者ipcs -m -p -i<shmid>查找附加到特定共享内存段的进程
# 方法 1: 通过 /proc/sysvipc/shm 查找cat/proc/sysvipc/shm|awk'$2== <shmid> {print "nattch:",$7, "cpid:",$5, "lpid:",$6}'# 方法 2: 结合 ps 查看进程信息SHMID=32769LPID=$(ipcs -m -p -i $SHMID|awk'NR > 3 {print$8}')if[-n"$LPID"]&&["$LPID"!="lpid"];thenps-p$LPID-o pid,cmdfi监控共享内存使用情况
# 实时监控共享内存的附加情况watch-n1'ipcs -m | awk "NR > 3 && \$6> 0 {print}"'# 或者使用更详细的监控watch-n1'ipcs -m -p | awk "NR > 3 && \$6> 0 {print}"'判断流程总结
快速判断: 查看
nattch字段nattch = 0: 没有进程附加nattch > 0: 有进程附加
查看进程信息: 使用
ipcs -m -p查看创建者和最后操作者 PID详细信息: 查看
/proc/sysvipc/shm获取完整信息确认进程: 使用
ps命令确认进程是否仍在运行
注意事项:
nattch字段是最可靠的判断依据lpid是最后操作的进程, 不一定是当前附加的进程- 如果进程异常退出未调用
shmdt(),nattch可能不会立即更新 - 系统重启后, 所有共享内存段都会被清除
相关命令说明
ipcs 命令
ipcs用于显示 IPC 对象(消息队列、共享内存、信号量)的信息.
常用选项:
-m: 显示共享内存段信息-q: 显示消息队列信息-s: 显示信号量信息-a: 显示所有 IPC 对象信息-l: 显示系统限制-i <id>: 显示指定 ID 的详细信息-p: 显示创建者和最后操作者的 PID-t: 显示时间信息
ipcrm 命令
ipcrm用于删除 IPC 对象.
常用选项:
-m <shmid>: 根据 shmid 删除共享内存段-M <key>: 根据键值删除共享内存段-q <msqid>: 根据 msqid 删除消息队列-Q <key>: 根据键值删除消息队列-s <semid>: 根据 semid 删除信号量-S <key>: 根据键值删除信号量
扩展阅读
man 1 ipcs- 查看 IPC 对象信息man 1 ipcrm- 删除 IPC 对象man 2 shmget- 创建/获取共享内存段man 2 shmctl- 控制共享内存段