生成一个后台进程并阻塞等待它完成
Posted
技术标签:
【中文标题】生成一个后台进程并阻塞等待它完成【英文标题】:Spawn a background process and have a blocking wait on it to finish 【发布时间】:2021-07-26 09:49:07 【问题描述】:我的场景是这样的:我需要在后台从另一个 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】:我不确定它是否适合您的应用程序,但我通常使用多处理模块中的events
。
这个概念是一个非常简单的信号行为,因为所有线程/进程都可以访问这个信号。在你的情况下,它会像:
-
清除进程 1 中的事件 -
event.clear()
启动进程 2
等待进程 1 中的事件 - event.wait()
完成后在进程 2 中设置事件 - event.set()
一旦调用event.set()
,所有等待此事件的进程/线程都会立即恢复工作。
【讨论】:
以上是关于生成一个后台进程并阻塞等待它完成的主要内容,如果未能解决你的问题,请参考以下文章