如何使可能无限循环的程序超时

如何使可能无限循环的程序超时

假设我运行一个我怀疑包含无限循环的程序,或者一些其他可能运行时间过长的代码。我知道在 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您指定超时时发送的信号。

相关内容