2

我正在编写几个 shell 脚本来做一些事情:

  1. main.sh在 screen 下运行,它设置一些变量,然后在前台调用: start.sh (no &)

  2. start.sh运行,它设置一些 Java 特定的变量,并启动一个Java进程(再次在前台

  3. Java运行并执行它的操作,直到收到“退出”命令。(也在前台

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

  - main.sh
    \- 开始.sh
      \- 爪哇

问题是 Java 程序有时会进入一种不尊重您的“退出”命令的时髦状态,并愉快地坐在那里做自己的事情。我一直在将此 Java 进程的进程 ID 保存到 PID 文件中,并向这些 Java 进程发送 -STOP(17?) -TERM(15) 和 KILL(9) 信号,但似乎没有什么可以正确地杀死它们。

我可以杀死 -9 'start.sh' 进程,它确实杀死了进程树,但使 Java 进程处于可怕的已失效(僵尸)状态,唯一的解决方案是重新启动服务器。

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

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

提前致谢,

4

2 回答 2

4

僵尸死了。如果你想让他们在原地休息,你的父母(main.sh / start.sh)必须wait/waitpid它。

于 2011-07-07T06:25:40.873 回答
3

你有没有看过这样的电影,巫师挥动他的魔杖,他周围的每个人都像雕像一样僵住,然后再次挥动它,他们像以前一样继续?这是需要的kill -STOP,并且没有任何过程可以保护自己免受它的影响。

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

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

如果您kill -STOP是父 shell,它将无法响应通知子进程已完成的子进程,因此子进程将成为僵尸,直到您使用kill -CONT.

于 2011-11-26T10:42:12.793 回答