下面的脚本会挂起,直到您按 Ctrl + C ,然后关闭需要两秒钟。我写这篇文章是为了调查Java的process.destroy()
#! /usr/bin/env bash
# dieslowly.sh
bail() {
echo exiting...
sleep 2
echo ...exited
trap - SIGINT SIGTERM
kill -- -$$
}
trap bail SIGTERM SIGINT
echo "running..."
sleep infinity
我认为它有效,因为:
./dieSlowly.sh
并按 Ctrl + C ,则会等待两秒钟然后退出./dieSlowly.sh
,然后在另一个终端运行kill -2 -<pid>
,则等待两秒钟然后退出此(Java)测试调用bash脚本,并尝试允许它慢慢关闭
void kill_dummy()
{
// Run the test script
Process process = new ProcessBuilder("./dieSlowly.sh").start();
// terminate the process, wait for it to stop, then kill it
DateTime before = new DateTime();
process.destroy(); // this doesn't seem to do anything
// Runtime rt = Runtime.getRuntime();
// rt.exec('kill -9 ' + process.pid); // this kills it too fast
// rt.exec('kill -2 -' + process.pid); // this doesn't kill it at all
// rt.exec('kill -2 ' + process.pid); // neither does this
process.waitFor(4, TimeUnit.SECONDS);
process.destroyForcibly();
DateTime after = new DateTime();
// expect it to have taken less than four secongs
assert (after.getMillis() - before.getMillis() < 4000);
}
我希望测试大约需要两秒钟 - 这是脚本自行关闭所需的时间。
相反,它需要大约四秒钟。使用调试器我已验证destroy()
调用无效。这会导致waitFor
超时。 destroyForcibly()
然后以极端的偏见杀死这个过程 - 我想避免这种过程。
如果我在destroyForcibly()
上放置断点,则ps axjf
命令会显示此树:
\_ -zsh
| \_ /bin/sh /opt/idea-IC-172.4343.14/bin/idea.sh /path/to/my/project
| \_ idea
| \_ idea
| \_ bash ./dieSlowly.sh
| \_ sleep infinity
\_ -zsh
| \_ -zsh
| \_ bash ./dieSlowly.sh
| \_ sleep infinity
我可以进行哪些修改,以便测试在测试中触发慢速关闭路径?
我知道信号是特定于操作系统的东西,而JVM因其打算独立于操作系统而受到限制。但是,当我从JVM运行kill -9 <pid>
时,我成功地终止了进程,所以似乎可以将命令中继到操作系统并让它发送信号。
假设我无法使用process.destroy()
,那么问题就变成了:
为什么我可以从JVM调用
kill -9
,而不是kill -2
?