【问题标题】:Delete all SYSTEM V shared memory and semaphores on UNIX-like systems删除类 UNIX 系统上的所有 SYSTEM V 共享内存和信号量
【发布时间】:2026-02-06 02:30:01
【问题描述】:

如何在类 UNIX 系统(例如 Ubuntu)上使用单个命令删除所有未使用的信号量和共享内存?

【问题讨论】:

  • 这个问题确实需要“为什么”的解释。
  • 我正在用 c 做一个学校项目
  • 那么,像往常一样做作业,你知道什么,你尝试过什么?
  • 我正在使用网络文件系统中的信号量和共享内存
  • 各位好神,表现出一点理解。我现在也想到了同样的问题。注册一些 sys v 共享内存并在一段时间后需要清理,谁想要多次调用“ipcrm”,事先解析“ipcs”。编程就是懒惰。而且 * 尤其适合懒惰的程序员,不是吗?

标签: linux unix posix semaphore shared-memory


【解决方案1】:
#!/bin/bash
ipcs -m | grep `whoami` | awk '{ print $2 }' | xargs -n1 ipcrm -m
ipcs -s | grep `whoami` | awk '{ print $2 }' | xargs -n1 ipcrm -s
ipcs -q | grep `whoami` | awk '{ print $2 }' | xargs -n1 ipcrm -q

【讨论】:

  • 这是一个很好的答案,它帮助我删除了密钥为 0x0 的队列(无法使用 ipcrm -Q 选项删除)
【解决方案2】:

1 行就可以了

对于消息队列

ipcs -q | sed "$ d; 1,2d" |  awk '{ print "Removing " $2; system("ipcrm -q " $2) }'

ipcs -q会给出消息队列的记录

sed "$ d; 1,2d " 将删除最后一个空白行 ("$ d") 和前两个标题行 ("1,2d")

awk 将完成剩下的工作,即使用命令"ipcrm -q" w.r.t 打印和删除。第 2 列的值 (coz $2)

【讨论】:

    【解决方案3】:

    删除 FreeBSD 上的所有共享内存段

    #!/bin/sh
    for i in $(ipcs -m | awk '{ print $2 }' | sed 1,2d);
    do
        echo "ipcrm -m $i"
        ipcrm -m $i
    done
    

    删除所有信号量

    #!/bin/sh
    for i in $(ipcs -s | awk '{ print $2 }' | sed 1,2d);
    do
        echo "ipcrm -s $i"
        ipcrm -s $i
    done
    

    【讨论】:

      【解决方案4】:

      检查是否有要删除的内容:

      ipcs -a | grep `whoami`
      

      在 linux 上通过以下方式全部删除:

      ipcs | nawk -v u=`whoami` '/Shared/,/^$/{ if($6==0&&$3==u) print "ipcrm shm",$2,";"}/Semaphore/,/^$/{ if($3==u) print "ipcrm sem",$2,";"}' | /bin/sh
      

      对于太阳来说是:

      ipcs -a | nawk -v u=`whoami` '$5==u &&(($1=="m" && $9==0)||($1=="s")){print "ipcrm -"$1,$2,";"}' | /bin/sh
      

      感谢 di.uoa.gr

      再次检查是否一切正常

      用于删除 您的 sems/shared mem - 假设您是工作站中没有管理员权限的用户

      【讨论】:

        【解决方案5】:

        除了 bvamos 的回答,根据文档,sem 的使用已被弃用:

        NAME ipcrm - 删除消息队列、信号量集或共享内存 ID 概要 ipcrm [ -M 键 | -m id | -Q 键 | -q id | -S 键 | -s id] ... 已弃用的用法

        ipcrm [ shm |味精 | sem ] id ...

        删除共享内存

        我们 ipcrm -m 按 id 删除共享内存段

        #!/bin/bash
        
        set IPCS_M = ipcs -m | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f2 -d" "
        
        for id in $IPCS_M; do
          ipcrm -m $id;
        done
        

        ipcrm -M 键删除共享内存段

        #!/bin/bash
        
        set IPCS_M = ipcs -m | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f1 -d" "
        
        for id in $IPCS_M; do
          ipcrm -M $id;
        done
        

        删除消息队列

        我们 ipcrm -q 按 id 删除共享内存段

        #!/bin/bash
        
        set IPCS_Q = ipcs -q | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f2 -d" "
        
        for id in $IPCS_Q; do
          ipcrm -q $id;
        done
        

        ipcrm -Q按键删除共享内存段

        #!/bin/bash
        
        set IPCS_Q = ipcs -q | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f1 -d" "
        
        for id in $IPCS_Q; do
          ipcrm -Q $id;
        done
        

        移除信号量

        我们 ipcrm -s 按 id 删除信号量段

        #!/bin/bash
        
        set IPCS_S = ipcs -s | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f2 -d" "
        
        for id in $IPCS_S; do
          ipcrm -s $id;
        done
        

        ipcrm -S 按键删除信号量段

        #!/bin/bash
        
        set IPCS_S = ipcs -s | egrep "0x[0-9a-f]+ [0-9]+" | grep $USERNAME | cut -f1 -d" "
        
        for id in $IPCS_S; do
          ipcrm -S $id;
        done
        

        【讨论】:

          【解决方案6】:

          这就是我在 FreeBSD 中的做法:

          #!/usr/local/bin/bash for i in $(ipcs -a | grep "^s" | awk '{ print $2 }'); 做 回声“ipcrm -s $i” ipcrm -s $i 完毕

          【讨论】:

            【解决方案7】:

            这适用于我的 Mac OS:

            for n in `ipcs -b -m | egrep ^m | awk '{ print $2; }'`; do ipcrm -m $n; done
            

            【讨论】:

              【解决方案8】:

              在这里,保存并在你的 shell 上尝试这个脚本 (kill_ipcs.sh):

              #!/bin/bash
              
              ME=`whoami`
              
              IPCS_S=`ipcs -s | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
              IPCS_M=`ipcs -m | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
              IPCS_Q=`ipcs -q | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
              
              
              for id in $IPCS_M; do
                ipcrm -m $id;
              done
              
              for id in $IPCS_S; do
                ipcrm -s $id;
              done
              
              for id in $IPCS_Q; do
                ipcrm -q $id;
              done
              

              每当我们在大学生服务器上运行 IPCS 程序时,我们都会使用它。有些人并不总是清理所以......需要它:P

              【讨论】:

              • 谢谢。正是我想要的。
              • 即使nattach 不为零,这不会删除所有这些吗?这个呢?:ipcs -m | egrep "0x[0-9a-f]+ [0-9]+"|awk '{ if ($6 == 0) { print $2; } }'|xargs -n1 ipcrm -m
              • 我会将 for 循环替换为 xargs: echo $IPCS_S | xargs -n1 ipcrm -s
              • 对我来说,上面的正则表达式不起作用。以下做了IPCS_Q=ipcs -q | egrep -i "0x[0-9a-f]+.*[0-9]+" | grep $ME |剪切 -f2 -d" "``
              • 在 AIx 系统上也不起作用.. 对命令进行一些小的调整就可以了! ipcs -s |grep $ME | awk '{print $2}'awk命令解决定位问题。
              【解决方案9】:
              ipcs -s | grep $USERNAME | perl -e 'while (<STDIN>) { @a=split(/\s+/); print `ipcrm sem $a[1]`}'
              

              ipcs -s | grep $USERNAME | awk ' { print $2 } ' | xargs ipcrm sem
              

              将 $USERNAME 更改为真实用户名。

              【讨论】:

                【解决方案10】:

                既然您提到您正在使用 NFS 系统,您是否有权访问这些信号量和shared memory?我认为您误解了它们是什么,它们是使进程能够相互通信的 API 代码,semaphores 是防止竞争条件和线程相互通信的解决方案,简单的回答是,它们不会离开任何文件系统上的任何残留物。

                除非您使用的是套接字或管道?您是否具有删除它们的必要权限,为什么它们在 NFS 系统上?

                希望这会有所帮助, 最好的祝福, 汤姆。

                【讨论】:

                • 不,这对我没有帮助...我只是在为一个假的 nfs 做一个简单的 c 项目...我知道什么是信号量和共享内存...我只是想做对我的代码进行一些测试,我需要一键删除所有共享数据
                • @simone:您应该在原始问题上声明“假 nfs”,并指出您了解信号量和共享内存......仍然不清楚什么是“共享数据”?
                • 并且还包含代码以向我们 SO'ers 展示您的家庭作业......这也会有所帮助......
                【解决方案11】:

                我不知道如何一次全部删除,但是你可以使用ipcs列出资源,然后使用循环和删除ipcrm。这应该可行,但需要做一些工作。我记得我在课堂上做过一次。

                【讨论】:

                • 我们知道他使用的是SysV ipc而不是POSIX吗?
                • @Duck 我们知道他在使用 Ubuntu,我在 Ubuntu 上检查了这些命令
                • 对,但 ipcs 仅适用于 SysV ipc 对象。如果他使用的是 posix 版本,它们将显示在 /dev/shm 中,他可以在其中 rm 。