【问题标题】:Python subprocess call with output and timeout具有输出和超时的 Python 子进程调用
【发布时间】:2023-01-19 22:01:27
【问题描述】:

概括:我想从 Python(3.6 版)启动一个外部进程,非阻塞地轮询结果,并在超时后终止。

细节:有一个外部过程有两个“坏习惯”:

  1. 它在未定义的时间后打印出相关结果。
  2. 打印出结果后不停止。

    例子:也许下面的简单应用程序大部分类似于要调用的实际程序(mytest.py;源代码不可用):

    import random
    import time
    
    print('begin')
    time.sleep(10*random.random())
    print('result=5')
    while True: pass
    

    这就是我试图称呼它的方式:

    import subprocess, time
    myprocess = subprocess.Popen(['python', 'mytest.py'], stdout=subprocess.PIPE)
    for i in range(15):
        time.sleep(1)
        # check if something is printed, but do not wait to be printed anything
        # check if the result is there
        # if the result is there, then break
    myprocess.kill()
    

    我想在评论中实现逻辑。

    分析

    以下是不合适的:

    • 使用myprocess.communicate(),因为它等待终止,而子进程不会终止。
    • 杀掉进程然后调用myprocess.communicate(),因为我们不知道具体什么时候打印出结果
    • 使用process.stdout.readline() 因为那是一个 blocikg 语句,所以它会一直等到打印出一些东西。但这里最后不打印任何东西。

    myprocess.stdout 的类型是io.BufferedReader。所以问题实际上是:有没有办法检查是否有东西打印到io.BufferedReader,如果是,请阅读它,否则不要等待?

【问题讨论】:

    标签: python subprocess


    【解决方案1】:

    我想我得到了您需要的确切包裹。 认识command_runner,它是一个子进程包装器,允许:

    • 实时标准输出/标准错误输出
    • 无论执行如何超时
    • 进程树包括在超时情况下杀死的子进程
    • stdout / stderr 重定向到队列、文件或回调函数

    使用pip install command_runner安装

    用法:

    from command_runner import command_runner
    
    def callback(stdout_output):
        # Do whatever you want here with the output
        print(stdout_output)
    
    exit_code, output = command_runner("python mytest.py", timeout=300, stdout=callback, method='poller')
    
    if exit_code == -254:
        print("Oh no, we got a timeout")
        print(output)
    
    # Check for good exit_code and full stdout output here
    

    如果达到超时,您将得到 exit_code -254,但仍然会得到包含您的子进程写入 stdout/stderr 的任何内容的输出。

    免责声明:我是command_runner的作者

    在 github 页面上可以看到使用队列的其他非阻塞示例。

    【讨论】:

      猜你喜欢
      • 2011-04-04
      • 2012-08-24
      • 2014-05-17
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 2016-11-19
      相关资源
      最近更新 更多