假设我运行一个我怀疑包含无限循环的程序,或者一些其他可能运行时间过长的代码。我知道在 Linux 中我可以这样做:
timeout 1 ./program
给程序一个 1 秒的超时时间。但是,如果我理解正确的话,这只会向程序发送“SIGTERM”信号 - 程序可能会忽略它。无论如何,有什么更安全的方法可以确保程序在 1 秒后停止?
我想到的一种解决方案是在 bash 中运行程序并超时 bash,如下所示:
timeout 1 bash -c './program'
然后,1 秒后,bash 终止,因此它运行的程序也终止。这是一个好的解决方案吗?
答案1
这实际上取决于您所说的“安全”是什么意思。您有两种选择来终止进程:
- 礼貌地要求进程自行终止(例如使用 SIGTERM)
- 不客气地要求内核强行杀死它(例如:
kill -9
)
在大多数情况下,终止进程的最干净、“最安全”的方法是使用 SIGTERM 礼貌地询问它。这是因为默认情况下程序会将 SIGTERM 传播到其所有子进程,从而清理整个进程树。这也更好,因为终止进程有时间干净地关闭它们正在做的事情(刷新缓冲区等)。
当您强制终止进程时,这并不一定(甚至默认情况下)终止子进程。它有留下孤儿的倾向。它还容易损坏文件并通常会造成一些混乱。因此,kill -9
不应自动使用强制终止 () 进行清理。
Bash 脚本清理起来特别棘手。默认情况下,它们会将 SIGTERM 传播到其子进程并等待其子进程终止。如果由于某种原因你将 SIGTERM 发送到 bash 脚本并且它没有终止,那么kill -9
几乎肯定会留下孤儿。
要强制杀死它们,您需要强制杀死脚本和强行杀死所有的孩子。这通常很混乱,不建议作为自动操作。
幸运的是timeout
是意识到子进程的问题并根据要求清除整个进程树。
timeout -s 9 20 myscript
将强制杀死所有子进程。请注意,这仍然是关闭命令的“肮脏”方式,因为它们没有机会正确清理自身并可能损坏文件。
答案2
-s
该命令的选项允许timeout
您指定超时时发送的信号。