C语言 僵尸进程不能被杀死

m4pnthwp  于 2023-04-05  发布在  其他
关注(0)|答案(6)|浏览(382)

有办法杀死僵尸进程吗?我试过调用exit来杀死进程,甚至向进程发送SIGINT信号,但似乎没有什么可以杀死它。我正在为Linux编程。

kknvjkwl

kknvjkwl1#

僵尸进程已经死了,所以它们不能被杀死,只能被收割,这必须由它们的父进程通过wait*()完成。这通常被称为child reaper习惯用法,在SIGCHLD的信号处理程序中:

while (wait*(... WNOHANG ...)) {
    ...
}
3wabscal

3wabscal2#

这是我创建的一个杀死所有僵尸进程的脚本。它使用GDB调试器附加到父进程并发送waitpid来杀死僵尸进程。这将使父进程保持活动状态,只杀死僵尸进程。
需要安装GDB调试器,并且您需要登录并具有附加到进程的权限。这已经在Centos 6.3上进行了测试。

#!/bin/bash
##################################################################
# Script: Zombie Slayer
# Author: Mitch Milner
# Date:   03/13/2013 ---> A good day to slay zombies
#
# Requirements: yum install gdb
#               permissions to attach to the parent process
#
# This script works by using a debugger to
# attach to the parent process and then issuing
# a waitpid to the dead zombie. This will not kill
# the living parent process.
##################################################################

clear
# Wait for user input to proceed, give user a chance to cancel script
echo "***********************************************************"
echo -e "This script will terminate all zombie process."
echo -e "Press [ENTER] to continue or [CTRL] + C to cancel:"
echo "***********************************************************"
read cmd_string
echo -e "\n"

# initialize variables
intcount=0
lastparentid=0

# remove old gdb command file
rm -f /tmp/zombie_slayer.txt

# create the gdb command file
echo "***********************************************************"
echo "Creating command file..."
echo "***********************************************************"
ps -e -o ppid,pid,stat,command | grep Z | sort | while read LINE; do
  intcount=$((intcount+1))
  parentid=`echo $LINE | awk '{print $1}'`
  zombieid=`echo $LINE | awk '{print $2}'`
  verifyzombie=`echo $LINE | awk '{print $3}'`

  # make sure this is a zombie file and we are not getting a Z from
  # the command field of the ps -e -o ppid,pid,stat,command
  if [ "$verifyzombie" == "Z" ]
  then
    if [ "$parentid" != "$lastparentid" ]
    then
      if [ "$lastparentid" != "0" ]
      then
        echo "detach" >> /tmp/zombie_slayer.txt
      fi
    echo "attach $parentid" >> /tmp/zombie_slayer.txt
    fi
    echo "call waitpid ($zombieid,0,0)" >> /tmp/zombie_slayer.txt
    echo "Logging: Parent: $parentid  Zombie: $zombieid"
    lastparentid=$parentid
  fi
done
if [ "$lastparentid" != "0" ]
then
  echo "detach" >> /tmp/zombie_slayer.txt
fi

# Slay the zombies with gdb and the created command file
echo -e "\n\n"
echo "***********************************************************"
echo "Slaying zombie processes..."
echo "***********************************************************"
gdb -batch -x /tmp/zombie_slayer.txt
echo -e "\n\n"
echo "***********************************************************"
echo "Script complete."
echo "***********************************************************"

好好享受。

gajydyqb

gajydyqb3#

僵尸进程是一个进程ID(以及相关的终止状态和资源使用信息)。消除它的唯一方法是让它的父进程等待它(有时候,如果父节点有bug,并且有一个争用条件,它错过了等待的机会,那么可以通过手动发送SIGCHLD到父节点来实现),但通常情况下,您需要将SIGCHLD发送到父节点。你运气不好,除非你强行终止父母。

**编辑:**另一种方法,如果你很绝望,不想杀死父节点,那就是用gdb附加到父节点,并在僵尸子节点上强制调用waitpid

jgwigjjp

jgwigjjp4#

kill -17 ZOMBIE_PID

kill -SIGCHLD ZOMBIE_PID
可能会工作,但就像其他人说的,它正在等待父调用wait(),所以除非父没有收割就死了,它因为某种原因卡在那里,你可能不想杀死它。

ikfrs5lh

ikfrs5lh5#

如果我没记错的话,杀死僵尸进程的父进程将允许僵尸进程死亡。
使用ps faux得到一个显示父/子进程关系的运行进程的层次树。

vyswwuz2

vyswwuz26#

请参阅unix-faqs“如何摆脱持续存在的僵尸进程?”
你不能杀死僵尸,因为他们已经死了。但如果你有太多的僵尸,然后杀死父进程或重新启动服务。
您可以尝试使用其PID杀死僵尸进程

kill -9 pid

请注意kill-9并不能保证杀死僵尸进程

相关问题