【问题标题】:Linux, timing out on subprocessLinux,子进程超时
【发布时间】:2011-08-30 13:42:46
【问题描述】:
好的,我需要编写一个调用脚本的代码,如果脚本中的操作挂起,则终止进程。
首选语言是 Python,但我也在查看 C 和 bash 脚本文档。
似乎是一个简单的问题,但我无法确定最佳解决方案。
从目前的研究来看:
- Python:在虚拟机使用的地方有一些奇怪的线程模型
一次一个线程,不行吗?
- C: 到目前为止,首选的解决方案似乎是使用 SIGALARM + fork +
执行。但是 SIGALARM 不是堆安全的,所以它可以丢弃所有东西?
- Bash:超时程序?不是所有发行版的标准?
由于我是 Linux 新手,我可能不知道这些功能有 500 种不同的陷阱,所以谁能告诉我最安全和最干净的方法是什么?
【问题讨论】:
标签:
linux
process
timeout
【解决方案1】:
避免使用SIGALRM,因为在信号处理程序中没有太多安全的事情可做。
考虑到您应该使用的系统调用,在 C 中,在执行 fork-exec 启动子进程后,您可以定期调用 waitpid(2) 并使用 WNOHANG 选项检查子进程是否仍在运行。如果waitpid返回0(进程仍在运行)并且期望的超时已经过去,您可以kill(2)子进程。
【解决方案2】:
在 bash 中你可以做类似的事情:
- 在后台使用 & 启动脚本/程序
- 获取后台进程的进程id
- 睡一会
- 然后杀掉进程(如果它完成了你不能杀掉它)或者你可以检查进程是否还活着然后杀掉它。
例子:
sh long_time_script.sh &
pid=$!
sleep 30s
kill $pid
您甚至可以尝试使用 trap 'script_stopped $pid' SIGCHLD - 请参阅 bash man 了解更多信息。
更新:我找到了其他命令timeout。它完全符合您的需要 - 运行有时间限制的命令。示例:
timeout 10s sleep 15s
将在 10 秒后杀死 sleep。
【解决方案3】:
有一组 Python 代码具有执行此操作的功能,如果您了解 API,则不会有太多困难。
Pycopia 集合具有用于超时功能的调度程序模块,以及用于生成子进程并向其发送信号的 proctools 模块。在这种情况下可以使用kill方法。