杀死僵尸进程,了解linux C中的PID

杀死僵尸进程,了解linux C中的PID,c,linux,process,zombie-process,C,Linux,Process,Zombie Process,我必须在LinuxC中杀死/清理一个僵尸进程。我所知道的只是僵尸的PID 我正在循环中创建几个僵尸进程: int i = 0; for (i; i<5; i++) { system("(: & exec sleep 30) &"); // create zombie for 30 sec } 但是如何仅使用PID杀死/清理它们? 我将PID保存在变量和标准信号中: kill(PID,9) 甚至都不起作用,因为这个过程已经死了。 还有其他的方法吗?请不要问我为什么要

我必须在LinuxC中杀死/清理一个僵尸进程。我所知道的只是僵尸的PID

我正在循环中创建几个僵尸进程:

int i = 0;
for (i; i<5; i++)
{
  system("(: & exec sleep 30) &"); // create zombie for 30 sec
}
但是如何仅使用PID杀死/清理它们? 我将PID保存在变量和标准信号中:

kill(PID,9) 
甚至都不起作用,因为这个过程已经死了。
还有其他的方法吗?请不要问我为什么要制造僵尸来杀他们。事实并非如此。

僵尸是一个已经死亡的过程。你不能再杀了它


僵尸实际上只是流程表中包含流程退出状态的一个条目。为了摆脱它,父进程必须调用wait来检索该信息。或者,父进程可以自行退出;然后,子进程成为所谓的孤儿,并被ID为1的进程init采用。init会自动获取所有死去的孩子。

你说的没错,你不能杀死僵尸,因为他们已经死了

他们之所以是僵尸,是因为进程已完成,但父进程尚未获取退出代码

最终,如果僵尸变成孤儿,init应该为您做这件事。真正的僵尸(仍然有父进程但父进程尚未获取退出代码的进程)将持续存在,直到:

父项不获取退出代码;或 当父对象退出时,它将成为孤立对象。
你所做的事情似乎很扭曲。我将假设您已经尝试创建了一个最小的测试用例来显示更广泛的问题和答案——当feather进程不清理waitpid调用和它的子进程资源时,就会创建一个僵尸

因此,要么正确地编写父进程代码以响应SIGCHLD并调用waitpid,要么,如果您无法控制父进程(我猜这里就是这种情况),则杀死父进程并将SIGTERM发送给父进程


后者起作用的原因是,所有无父子女都重新成为初始PID 1的父母,该PID 1将执行所需的清理。

您可以尝试使用SIGCHLD信号。对于C中的示例:

signal(SIGCHLD, handleSIGCHLD);


  void handleSIGCHLD(int signum) {
  int stat;

 /*Kills all the zombie processes*/
  while(waitpid(-1, &stat, WNOHANG) > 0);
}

下面是我创建的一个脚本,用于杀死所有僵尸进程。它使用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 "***********************************************************"

享受。

阅读以下内容:@Rajesh我没有父母的PID,使用bash创建。@Rajesh sudo kill-kill 1可以肯定。@danielfescher没有什么比拉电源线更好的了@拉杰什,我得离开键盘去做那件事。我听说这种方法在笔记本电脑上不太可靠,但如何做到呢。我没有父母。我正在使用bash创建僵尸。为什么不首先停止创建僵尸呢?因为我的客户想要它们。这有点混乱,但我必须创建一个删除它们的方法。请阅读第一个问题的结尾:我不是为了好玩。这些信息实际上决定了你将得到的解决方案,因为现在还不清楚问题到底是什么。我没有一个真正的父PID。你建议杀掉init进程吗?@krzakov,甚至不要考虑杀掉init进程的最小可能性。这一定是一种清理混乱的方法。但在我的程序中,我只能通过他的PID杀掉僵尸。不是所有的。@krzakov你不能杀死僵尸;他们已经死了。杀死/清除任何东西。如果你能对两个问题给出完全相同的答案,那么这表明这些问题是重复的。你不应该发布第二个答案,而应该以重复的方式标记或投票结束。
#!/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 "***********************************************************"