【发布时间】:2011-03-12 08:40:40
【问题描述】:
我发现了一个奇怪的场景,如果我启动一个 java 程序并且我想用 CTRL+C 优雅地退出它不起作用/响应,我必须在程序上执行 CTRL+Z 这并不酷,执行 ps 会列出进程...任何人请。
【问题讨论】:
-
你能发布一些代码吗?
标签: java unix shell copy-paste
我发现了一个奇怪的场景,如果我启动一个 java 程序并且我想用 CTRL+C 优雅地退出它不起作用/响应,我必须在程序上执行 CTRL+Z 这并不酷,执行 ps 会列出进程...任何人请。
【问题讨论】:
标签: java unix shell copy-paste
在 Unix 下,当您尝试使用 ^C 中断命令行程序时,命令行程序可以很好地控制所发生的事情。在终端输入^C 的默认效果是让内核将SIGINT 信号发送到前台进程组,SIGINT 的默认行为是杀死它发送到的进程,但这两者都是可以改的。
您的问题最可能的原因是您的 Java 程序正在拦截 SIGINT 以便在退出之前进行一些清理,但是信号处理程序有问题,因此该进程实际上并没有退出。第二个最可能的原因是程序完全忽略 SIGINT。最不可能的原因是它将终端置于“原始模式”,因此^C 只是将一个值为 0x03 的字节传递到其标准输入(如果它这样做了,^Z 可能也不起作用)。
如果您有权访问程序的源代码,则可以尝试修复有缺陷的信号处理程序和/或使其停止忽略信号。否则,你有点过河了。您可以尝试^\(控制反斜杠),它会发送一个不同正常致命的信号(SIGQUIT),但这也不能保证有效,如果它确实有效,它可能给你留下一个巨大的“核心转储”文件来摆脱。
唯一 100% 确定消除故障进程的方法是向其发送信号 9 (SIGKILL)。与其他致命信号不同,不可能拦截、阻止或忽略那个信号。没有控制键发送信号9;你必须用^Z暂停进程,或者打开一个新的终端窗口/ssh会话,用ps找到进程ID,然后使用kill命令。总是在kill -9 PID 之前尝试kill PID。
【讨论】:
我遇到了同样的问题(在我的情况下是问题:)),我的问题是我使用 javaw 而不是 java 启动了应用程序。
javaw 在没有控制台的情况下运行应用程序,因此 CTRL+C 不起作用。
关于javaw和java之间区别的另一个问题-What is the difference between 'java', 'javaw', and 'javaws'?
【讨论】: