【问题标题】:Python: Using popen poll on background processPython:在后台进程上使用 popen poll
【发布时间】:2012-08-16 23:19:17
【问题描述】:

我正在后台运行一个很长的进程(实际上是另一个 python 脚本)。我需要知道它什么时候完成。我发现Popen.poll() 总是为后台进程返回 0。还有其他方法吗?

p = subprocess.Popen("sleep 30 &", shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)

上面的代码永远不会打印None

【问题讨论】:

  • 您正在使用 shell 后台语法 (&),这使得子进程启动一个子子进程,然后自行退出 - 这就是为什么您会得到 0 (process完成)而不是None(仍在运行)

标签: python python-3.x popen subprocess


【解决方案1】:

你不应该在最后运行你的脚本。因为 shell fork 你的进程并返回 0 退出代码。

【讨论】:

    【解决方案2】:

    我认为您需要 popen.wait()popen.communicate() 命令。 Communicate 将获取您放入PIPEstdoutstderr 数据。如果另一个项目是 Python 脚本,我会通过执行以下操作来避免运行 shell=True 调用:

    p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdout, stderr) = p.communicate()
    print(stdout)
    print(stderr)
    

    当然,它们持有主线程并等待其他进程完成,这可能很糟糕。如果您想忙着等待,那么您可以简单地将原始代码包装在一个循环中。 (顺便说一句,您的原始代码确实为我打印了“无”)

    循环解决方案的包装示例:

    p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    while p.poll() == None:
        # We can do other things here while we wait
        time.sleep(.5)
        p.poll()
    (results, errors) = p.communicate()
    if errors == '':
        return results
    else:
        raise My_Exception(errors)
    

    【讨论】:

    • 根据 dbr 的出色回答清理了我的循环示例(完全忘记添加睡眠调用以避免颠簸)
    【解决方案3】:

    你不需要使用shell后台&语法,因为subprocess会自己在后台运行进程

    只要正常运行命令,然后等Popen.poll返回not None

    import time
    import subprocess
    
    p = subprocess.Popen("sleep 30", shell=True)
    # Better: p = subprocess.Popen(["sleep", "30"])
    
    # Wait until process terminates
    while p.poll() is None:
        time.sleep(0.5)
    
    # It's done
    print("Process ended, ret code:", p.returncode)
    

    【讨论】:

      猜你喜欢
      • 2012-10-10
      • 1970-01-01
      • 2018-12-05
      • 2014-12-02
      • 1970-01-01
      • 2020-03-28
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多