生成一个后台进程并等待它完成

时间:2021-05-04 02:46:57

标签: python linux multiprocessing

我的场景是这样的:我需要在后台运行来自另一个 python 脚本(进程 1)的 python 脚本(进程 2)。我想在脚本 1 中的进程 2 上进行阻塞等待,因为我想使用脚本 2 输出的文件。例如,考虑这个最小的例子:

脚本 1

import subprocess
import time

def get_pid_from_line(line):
    temp = [x for x in line.split() if len(x) != 0]
    return int(temp[1])

def blocking_wait(pid):
    while True:
        ps_output = subprocess.check_output("ps -ef | grep -E 'python.*<defunct>'", shell=True).decode("utf-8")
        ps_list = [line.strip() for line in ps_output.split("\n") if len(line.strip()) != 0]
        ps_list = [get_pid_from_line(line) for line in ps_list]
    
        if(pid in ps_list):
            break
        
        time.sleep(5)

p = subprocess.Popen(["python", "test2.py", "&"], shell=False)  # shell false required to get the correct pid, no longer can use string command :P
print(p.pid, type(p.pid))
# subprocess.call(f"wait {p.pid}", shell=True) # this again doesn't work
blocking_wait(p.pid)
print("world")

脚本 2

import time
import sys

for i in range(10):
    print("hello")
    time.sleep(2)

此代码有效,但我面临的问题是脚本 2 完成后,进程 2(脚本 1 中的 pid p.pid)变成僵尸,因此我在僵尸 python 进程列表中搜索 pid .为什么会发生这种情况?此外,搜索 pid 是否是僵尸 python 进程的逻辑似乎很脆弱。我尝试使用 wait pid 但问题是它是非阻塞的,这会破坏我的逻辑,因为尚未创建文件。一般来说,这个解决方案有效但并不优雅,有没有更好的方法来做到这一点? TIA。

1 个答案:

答案 0 :(得分:0)

我不确定它是否适合您的应用程序,但我通常使用多处理模块中的 events

这个概念是一个非常简单的信号行为,因为所有线程/进程都可以访问这个信号。在你的情况下,它会像:

  1. 清除进程 1 中的事件 - event.clear()
  2. 开始流程 2
  3. 等待进程 1 中的事件 - event.wait()
  4. 完成后在进程 2 中设置事件 - event.set()

一旦调用 event.set(),等待此事件的所有进程/线程都会立即恢复工作。

相关问题