从shell中避免使用Zombie进程?

时间:2011-07-07 04:31:52

标签: linux shell unix process zombie-process

我正在写一些shell脚本,它们做了一些事情:

  1. main.sh 在屏幕下运行,它会设置一些变量,然后在前景中调用 start.sh (no&)
  2. 运行
  3. start.sh ,设置一些Java特定变量,并启动 Java 进程(再次在前景中)
  4. Java 运行并执行其操作,直到收到'quit'命令。 (也在前景

    所以我的进程树看起来像是:

  5.   - main.sh
        \- start.sh
          \- java
    

    问题有时候Java程序会处于一个时髦的状态,它不会尊重你的'quit'命令,并且快乐地坐在那里做它的事情。我一直在将这个Java进程的进程ID保存到PID文件中,并向这些java进程发送-STOP(17?) - STM(15)和KILL(9)信号,但似乎没有任何东西正确地将它们删除。

    我可以杀死-9'start.sh'进程,它确实杀死了进程树,但让Java进程处于可怕的失效(僵尸)状态,唯一的解决办法就是重启服务器。 / p>

    我想知道是否有人对如何避免陷入这些情况有任何意见,或者是否有任何可能阻止这些僵尸进程发生的Linux / shell功能。我还应该补充一点,我不能修改Java应用程序代码,因为它是一个专有的应用程序,而且我没有可用的源代码。

    这是在带有2.6.35.13-92.fc14.x86_64内核的Fedora 14上运行。

    提前致谢,

2 个答案:

答案 0 :(得分:4)

僵尸死了。如果您希望他们休息,您的父母(main.sh / start.sh)必须wait / waitpid

答案 1 :(得分:2)

你有没有见过其中一部电影,巫师挥动魔杖,周围的人像雕像一样冻结,再次挥动它们,它们像以前一样继续?那就是kill -STOP所做的,并且没有任何过程可以做些什么来保护自己。

我很惊讶你的java进程变成了僵尸,因为僵尸是已经完成的进程,只是在等待告诉他们的父进程他们已经完成了。但是父母必须要检查。大多数炮弹会定期检查。

如果您已经杀死了父进程,则子进程“更改父进程”并成为init(PID 1)的子进程。通常情况下,init总是会关注流程,告诉它已经完成了。

如果您kill -STOP是父shell,它将无法响应子进程通知他们已经完成,因此在您使用kill -CONT重新启动父级之前,该子级将变为僵尸。