代码之家  ›  专栏  ›  技术社区  ›  vikkyhacks

在子进程生成的进程终止之前,Popen.communicate一直处于停滞状态

  •  2
  • vikkyhacks  · 技术社区  · 7 年前

    我有下面三个脚本,当我运行main.py文件时,它会生成child.py,它会再次执行subchild.py并快速终止,subchild.py会持续执行很多时间。

    问题是,main.py在p.communicate()被阻塞,直到subchild.py终止。如果打开任务管理器并终止正在运行的subchild.py main.py,则立即返回child.py的输出

    • main.py应该只等待child.py终止,为什么要等待subchild.py终止呢?
        # main.py file
    
        if __name__ == '__main__':
            import subprocess
            p = subprocess.Popen(
                ["python", "child.py"],
                stdout=subprocess.PIPE,
                stdin=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            out, _ = p.communicate()
            print(out)
    
    
        # child.py file
    
        if __name__ == '__main__':
            import subprocess
            print("Child running")
            p = subprocess.Popen(["python", "subchild.py"])
            print("Child pid - ", p.pid)
            exit(1)
    
    
        # subchild.py file
    
        if __name__ == '__main__':
            import time
            time.sleep(10000)
    

    注意:我正在Windows7企业版上试用。我用的是python3.6.6

    process 对象。我也无法控制将接收哪个child.py命令作为main.py的输入,因此我需要不等待subchild.py并在完成后立即退出child.py的输出。

    3 回复  |  直到 7 年前
        1
  •  2
  •   user2357112    7 年前

    你的 communicate 打电话不只是等孩子完成。它首先尝试读取孩子的stdout和stderr的全部内容。

    即使孩子读完了,父母也不能停止阅读,因为 孙子继承孩子的stdin、stdout和stderr . 父级需要等待孙级完成,或者至少等待孙级关闭其stdout和stderr,然后父级才能确保已完成读取。

        2
  •  1
  •   LeKhan9    7 年前

    subprocess.call() Popen() 逻辑 call() 而不是逻辑。

    p = subprocess.call(["python", "subchild.py"])
    

    https://docs.python.org/2/library/subprocess.html#subprocess.call


    另一种方法是保留代码,因为它实际上是对使用 .call() 在main.py文件中。

    import subprocess
    p = subprocess.call(
        ["python", "child.py"],
        stdout=subprocess.PIPE,
        stdin=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    

    您提到不能使用.call(),因为您需要终止它,但事实并非如此。进行此更改应允许您:

    • 快速返回main.py和child.py,
    • 它将从child.py和
    • subchild.py将继续运行
        3
  •  1
  •   vikkyhacks    7 年前

    最后我自己找到了解决方法,这似乎是python的一个公开问题。很高兴看到这个修好。 https://bugs.python.org/issue26731