python - 子进程超时失败

标签 python subprocess

我想在子进程上使用超时

 from subprocess32 import check_output
 output = check_output("sleep 30", shell=True, timeout=1)

不幸的是,虽然这会引发超时错误,但它会在 30 秒后发生。 check_output好像不能打断shell命令。

我可以在 Python 方面做些什么来阻止这种情况? 我怀疑 subprocess32 未能终止超时进程。

最佳答案

check_output() with timeout is essentially :

with Popen(*popenargs, stdout=PIPE, **kwargs) as process:
    try:
        output, unused_err = process.communicate(inputdata, timeout=timeout)
    except TimeoutExpired:
        process.kill()
        output, unused_err = process.communicate()
        raise TimeoutExpired(process.args, timeout, output=output)

有两个问题:

它导致您观察到的行为:TimeoutExpired 发生在一秒钟内,shell 被杀死,但是 check_output() 仅在孙子之后的 30 秒内返回sleep 进程退出。

要解决这些问题,请终止整个进程树(属于同一组的所有子进程):

#!/usr/bin/env python3
import os
import signal
from subprocess import Popen, PIPE, TimeoutExpired
from time import monotonic as timer

start = timer()
with Popen('sleep 30', shell=True, stdout=PIPE, preexec_fn=os.setsid) as process:
    try:
        output = process.communicate(timeout=1)[0]
    except TimeoutExpired:
        os.killpg(process.pid, signal.SIGINT) # send signal to the process group
        output = process.communicate()[0]
print('Elapsed seconds: {:.2f}'.format(timer() - start))

输出

Elapsed seconds: 1.00

关于python - 子进程超时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36952245/

相关文章:

python - 如何在 Python 中运行另一个脚本而不等待它完成?

python - 子进程:执行两个或多个preexec_fn

postgresql - 如何在 Python 中使用正确的子进程 Pclose?

python - 如何告诉 MySQL 在更新/插入之前触发哈希?

python - 如何在Python中将http触发器Azure Function转换为Azure持久函数?

python - 设计——如何处理时间戳(存储)以及何时执行计算; Python

Python Popen 输出到 C 程序,fget 在循环中读取相同的 stdin

python - 从 subprocess.check_call() 获取输出时出现问题

python - 在单行文本文件中的数字后添加新行

python - Celery:实例在一两周后变得缓慢