我有几个模拟要做,每个模拟都用python simulate.py <parameter list>
.这些模拟的问题在于,其中一些模拟挂起而没有退出,这使我无法使用简单的脚本批量运行它们。
我需要的是某种形式的“运行时约束”命令,它会自动终止进程(最好通过虚拟按下Ctrl+C,但我认为简单的终止也可以)在指定的时间之后,如果进程没有自行优雅地结束。
当然,我可以自己编写这样的脚本,但我怀疑有人在我之前已经完成了,所以我不必花费大量时间与ps
、time
和 bash 手册重新发明轮子。
答案1
潜在的解决方案#1
使用timeout
命令:
$ date
Mon May 6 07:35:07 EDT 2013
$ timeout 5 sleep 100
$ date
Mon May 6 07:35:14 EDT 2013
如果一段时间后还没有停止,您也可以在timeout
命令和进程中放置一个守卫。kill
$ date
Mon May 6 07:40:40 EDT 2013
$ timeout -k 20 5 sleep 100
$ date
Mon May 6 07:40:48 EDT 2013
在进程sleep 100
应该停止后,这将等待最多 20 秒,如果它仍在运行,timeout
则会向其发送kill
信号。
潜在的解决方案#2
另一种方法虽然风险更大,但方法如下:
./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"
在 Stack Overflow 上的一个问题中找到了这种技术:限制程序在Linux中运行的时间。具体这个回答。
笔记:根据 @mattdm 留下的评论,上述方法可能存在风险,因为它假设自您的进程以来没有启动任何新进程。因此没有分配新的 PID。鉴于此,这种方法可能不应该被使用,但这里仅作为解决该问题的一般方法的参考。该timeout
方法是2种方法中较好的选择。
答案2
timeout
我发现了比:更好的东西timelimit
。
它有几个优点;一是用户可以通过按“Ctrl+C”手动中止执行。
该timelimit
程序可在 Debian 存储库中找到。
答案3
您可以使用 调整 cpu 时间和其他内容ulimit
,尤其是 cpu 时间:
$ ulimit -t 60 # limit to 60 seconds
$ program
答案4
Bash 使用一个名为它的变量$BASHPID
可以在这种情况下使用,例如:
#!/bin/bash
do_face() {
local parent=$1
echo $BASHPID > pid
sleep 10
echo "Killing parent $parent"
kill $parent
}
ME=$BASHPID
eval $(echo "do_face $ME &")
sleep 20 && kill $(cat pid) && echo "killed child $(cat pid)"
exit 1
您可以将调用中的参数更改为sleep
in do_face()
,100
而不是10
,看看当孩子花太长时间做家务时会发生什么。只需将对 sleep 的调用更改do_face()
为对可执行文件的调用,如果花费太长时间,脚本就会终止它,20
在此示例中,秒是限制值。可以实现参数,以便这成为一个简单的脚本来调用,并且可以由另一个脚本批量调用或以其他方式调用。处理每个并发进程的pid文件是一个需要处理的问题,也许使用不同的子目录......
注意:在 GNU Linux 上sleep
可以采用浮点参数,例如sleep 0.1
休眠十分之一秒。