【发布时间】:2010-03-05 14:41:17
【问题描述】:
在 Linux 中,我想运行一个程序,但只能运行有限的时间,比如 1 秒。如果程序超过此运行时间,我想终止该进程并显示错误消息。
【问题讨论】:
标签: linux
在 Linux 中,我想运行一个程序,但只能运行有限的时间,比如 1 秒。如果程序超过此运行时间,我想终止该进程并显示错误消息。
【问题讨论】:
标签: linux
嗯嗯。 timeout(1).
描述
启动 COMMAND,如果在 DURATION 后仍在运行,则将其终止。
【讨论】:
StackOverflow 不允许我删除我的答案,因为它已被接受。它获得了反对票,因为它位于列表的顶部,下面有一个更好的解决方案。如果您使用的是 GNU 系统,请按照@wRAR 的建议使用timeout。因此,希望您能停止投票,以下是它的工作原理:
timeout 1s ./myProgram
您可以使用s、m、h 或d 表示秒(如果省略,则为默认值)、分钟、小时或天。这里的一个很好的功能是,您可以指定另一个选项 -k 30s(在上面的 1s 之前)以便在再过 30 秒后使用 SIGKILL 杀死它,如果它不响应原始 SIGTERM。
一个非常有用的工具。现在向下滚动并向上投票@wRAR 的答案。
对于后人,这是我最初的 - 劣质 - 建议,如果对某人有用,它可能仍然是。
一个简单的 bash 脚本应该能够为您做到这一点
./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"
应该这样做。
$! 扩展为最后一个后台进程(通过使用&),如果它没有杀死任何进程,kill 返回 false,因此只有在实际杀死某些东西时才会执行 echo。
2>/dev/null 重定向 kill 的 stderr,否则它会打印一些信息告诉你它无法终止进程。
您可能还想添加-KILL 或任何您想用来摆脱进程的信号。
编辑
正如 ehemient 指出的那样,如果您的程序完成并且其他一些进程抢夺了 pid,那么这里会有一场比赛,它会被杀死。为了减少它发生的可能性,你可以对 SIGCHLD 做出反应,如果发生这种情况,不要试图杀死它。仍然有机会杀死错误的进程,但它非常遥远。
trapped=""
trap 'trapped=yes' SIGCHLD
./myProgram &
sleep 1
[ -z "$trapped" ] && kill $! 2>/dev/null && echo '...'
【讨论】:
PID=$!,设置trap 'PID=' SIGCHLD 和[ -n $PID ] && kill $pid,以便在(不太可能)您的孩子退出并且另一个进程开始重用相同的PID 的情况下,您不要杀死无辜的旁观者。
也许 CPU 时间限制 (ulimit -t/setrlimit(RLIMIT_CPU)) 会有所帮助?
【讨论】:
fork、setrlimit 和waitpid,然后检查它是否被 SIGXCPU 杀死。您还可以检查程序的返回值,当它被信号杀死时,bash 通常会将$? 设置为较高的值。不过不知道能不能确定是不是SIGXCPU。
WIFSIGNALED(status) 和 WTERMSIG(status),如果 status 由 wait* 返回。
您可以使用 & 在 shell 脚本中启动它
your_program &
pid=$!
sleep 1
if [ `pgrep $pid` ]
then
kill $pid
echo "killed $pid because it took too long."
fi
希望你明白这一点,我不确定这是否正确,我的 shell 技能需要一些更新 :)
【讨论】:
tail -f file & pid=$!
sleep 10
kill $pid 2>/dev/null && echo '...'
【讨论】:
如果你有资源,你可以在main() 的早期fork() 然后让父进程测量时间并可能杀死子进程。只需使用标准系统调用fork()、waitpid()、kill(),...也许是一些标准的 Unix 信号处理。不太复杂,但需要一些努力。
您也可以在 shell 上编写一些脚本,尽管我怀疑它是否会与 1 秒的时间一样准确。
如果您只想测量时间,请在 shell 上输入time <cmd ...>。
【讨论】:
好的,所以只需编写一个简短的 C 程序,forks,在子级调用 execlp 或类似的东西,测量父级和子级kills 的时间。应该很容易...
【讨论】: