当前位置: 首页 > 面试题库 >

子进程超时失败

经骁
2023-03-14
问题内容

我想在子流程上使用超时

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

不幸的是,尽管这会引起超时错误,但它会在30秒后发生。看来check_output无法中断shell命令。

我该如何在Python方面阻止这种情况?我怀疑subprocess32无法杀死超时的进程。


问题答案:

check_output()超时基本上是:

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)

有两个问题:

  • [第二个].communicate()可能会等待后代进程,而不仅是直接子进程,请参见Python子进程.check_call与.check_output
  • process.kill()可能不会杀死整个进程树,请参阅如何终止用shell = True启动的python子进程

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

要变通解决此问题,请杀死整个进程树(属于同一组的所有子进程):

#!/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的subprocess.Popen方法设置超时? 像这样: ? 问题答案: 我会建议采取看看类中的模块。我用它来实现超时。 首先,创建一个回调: 然后打开过程: 然后创建一个计时器,该计时器将调用回调,并将过程传递给它。 在程序后面的某个位置,您可能需要添加以下行: 否则,python程序将继续运行,直到计时器运行完毕。 编辑:我被告知, 在和条件之

  • 问题内容: 我正在python中使用subprocess模块​​运行一些shell脚本。如果shell脚本运行时间很长,我想杀死该子进程。我认为如果将其传递给我的陈述就足够了。 这是代码: 我已经用一些运行120秒的shell脚本测试了此调用。我期望子进程在30秒后被杀死,但是实际上该进程正在完成120秒脚本,然后引发了Timeout Exception。现在的问题是如何通过超时杀死子进程? 问题

  • 问题内容: 我想尽可能快地重复执行子过程。但是,有时该过程将花费很长时间,因此我想取消它。我使用signal.signal(…),如下所示: 但有时这段代码将尝试阻止下一轮执行。停止test / home / lu / workspace / 152 / treefit / test2超时/ bin / sh:/ home / lu / workspace / 153 / squib_driver

  • 问题内容: 目前,我使用以下命令执行本机进程: 假设我希望在经过一定时间后终止,而不是等待程序返回。我该怎么做呢? 问题答案: 这是Plexus CommandlineUtils的工作方式:

  • 问题内容: 有没有办法确保所有创建的子进程在Python程序退出时都消失了?所谓子流程,是指那些用subprocess.Popen()创建的内容。 如果不是,我是否应该遍历所有发出的终止点,然后终止-9?有什么清洁剂吗? 问题答案: 您可以为此使用 atexit ,并注册程序退出时要运行的所有清理任务。 atexit.register(func [,* args [, kargs]])** 在清理

  • 我正试图在设备上启动我的应用程序。它正在模拟器上成功发射。 null null 会不会是带有代码签名的东西? 目前我已将其设置为“不编码签名”