避免 shell 中的僵尸进程?
我正在编写几个 shell 脚本,它们执行以下操作:
main.sh 在屏幕下运行,它设置一些变量,然后调用:start.sh强>在前景(无&)
start.sh 运行,它设置一些 Java 特定变量,并启动 Java 进程(再次在前台)
Java 运行并执行其操作,直到收到“退出”命令。 (也在前景
所以我的进程树看起来像:
- main.sh \- start.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 上运行。
提前致谢,
I'm writing a couple shell scripts which do a few things:
main.sh run under screen, it sets some variables, then calls: start.sh in the foreground (no &)
start.sh is run, it sets some Java specific variables, and launches a Java process (again in the foreground)
Java runs and does its thing until receiving a 'quit' command. (also in the foreground
So my process tree then looks like:
- main.sh \- start.sh \- java
The problem is occasionally the Java program gets in a funky state where it doesn't honor your 'quit' command, and sits there merrily doing its thing. I have been saving the process ID of this Java process to a PID file, and sending -STOP(17?) -TERM(15) and KILL(9) signals to these java processes, but nothing seems to properly kill them off.
I can kill -9 the 'start.sh' process, which does kill off the process tree, but leaves the Java process in the dreaded defunct (zombie) state, to which the only solution is to reboot the server.
I was wondering if anyone had any input on how I might avoid getting into these situations, or if there is any Linux/shell feature I am missing that might prevent these zombie processes from occurring. I should also add I cannot modify the Java application code as it is a proprietary application, and I do not have the source code available.
This is running on Fedora 14 with the 2.6.35.13-92.fc14.x86_64 kernel.
Thanks in advance,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
僵尸死了。如果您希望它们保持原样,您的父母(main.sh / start.sh)必须
wait
/waitpid
它。Zombie are dead. If you want them rest in place, your parents (main.sh / start.sh) have to
wait
/waitpid
it.你是否看过这样的电影:巫师挥动魔杖,周围的每个人都像雕像一样冻结,然后再次挥动魔杖,他们又像以前一样继续?这就是
kill -STOP
所做的事情,并且进程无法采取任何措施来保护自己免受其影响。我很惊讶你的java进程变成了僵尸进程,因为僵尸进程已经完成并且只是等待告诉它们的父进程它们已经完成了。但家长一定要检查。大多数 shell 都会定期检查。
如果您已经杀死了父进程,则子进程“更改父进程”并成为
init
(PID 1) 的子进程。通常,init 总是关注告诉它已经完成的进程。如果您
kill -STOP
父 shell,它将无法响应子进程,通知它们已完成,因此子进程将变成僵尸,直到您使用kill 重新启动父进程-继续
。Have you ever seen one of those movies where the wizard waves his wand and everyone around him freezes like a statue, and waves it again and they continue as before? That's want
kill -STOP
does and there's nothing a process can do to protect itself from it.I'm surprised that your java processes become zombies because zombies are processes that have finished and are just waiting around to tell their parent process that they have finished. But the parent has to be checking. Most shells do check regularly.
If you've already killed the parent process, then the child process "changes parent" and becomes a child process of
init
(PID 1). Normally, init always pays attention to processes telling it they've finished.If you
kill -STOP
the parent shell, it won't be able to respond to child processes notifying that they've finished so the child will become a zombie until you restart the parent withkill -CONT
.