使用多处理时无法终止加载动画



我正在尝试使用多处理来运行多个脚本。一开始,我启动了一个加载动画,但我永远无法杀死它。下面是一个例子。。。

动画:foo.py

import sys
import time
import itertools
# Simple loading animation that runs infinitely.
for c in itertools.cycle(['|', '/', '-', '\']):
sys.stdout.write('r' + c)
sys.stdout.flush()
time.sleep(0.1)

有用的脚本:bar.py

from time import sleep
# Stand-in for a script that does something useful.
sleep(5)

尝试运行两者:

import multiprocessing
from multiprocessing import Process
import subprocess
pjt_dir = "/home/solebay/path/to/project" # Setup paths..
foo_path = pjt_dir + "/foo.py" # ..
bar_path = pjt_dir + "/bar.py" # ..
def run_script(path): # Simple function that..
"""Launches python scripts.""" # ..allows me to set a.. 
subprocess.run(["python", path]) # ..script as a process.
foo_p = Process(target=run_script, args=(foo_path,)) # Define the processes..
bar_p = Process(target=run_script, args=(bar_path,)) # ..
foo_p.start() # start loading animation
bar_p.start() # start 'useful' script 
bar_p.join() # Wait for useful script to finish executing
foo_p.kill() # Kill loading animation

我没有收到错误消息,(my_venv) solebay@computer:~$出现在我的终端中,但加载动画仍然存在(剪切我的名称和环境(。我怎样才能杀死它?

我以前也遇到过类似的情况,无法使用ctrl+c终止程序。这个问题(或多或少(通过使用守护进程/线程来解决(请参阅多处理文档(。要做到这一点,只需更改

foo_p = Process(target=run_script, args=(foo_path,)) 

foo_p = Process(target=run_script, args=(foo_path,), daemon=True) 

对于您想要创建的其他子进程也是如此。

话虽如此,我自己也不太确定这是否是解决无法终止多处理程序的问题的正确方法,还是只是一些人为因素恰好有助于解决这个问题。我建议更多地讨论守护进程线程的这个线程。但从本质上讲,根据我的理解,无论它们的父进程是否结束,守护进程线程都会自动终止。同时,如果线程不是守护进程,那么您需要等待子进程完成,然后才能完全终止程序。

您创建的进程太多。这两条线:

foo_p = Process(target=run_script, args=(foo_path,)) # Define the processes..
bar_p = Process(target=run_script, args=(bar_path,)) # ..

创建两个新流程。让我们一起"A";以及";B";。每个过程都包含以下功能:

def run_script(path): # Simple function that..
"""Launches python scripts.""" # ..allows me to set a.. 
subprocess.run(["python", path]) # ..script as a process.

然后创建另一个子流程。让我们把这两个过程称为";C";以及";D";。总的来说,您已经创建了4个额外的流程,而不仅仅是您需要的2个。它实际上是过程";C";它在终端上产生输出。此行:

bar_p.join()

等待";B";终止,这意味着";D";已终止。但这条线:

foo_p.kill() 

kills过程";A";但孤立进程";C";。因此,对终端的输出将永远持续。

这是有据可查的-请参阅多处理.terminate的描述,其中写道:

";请注意,进程的子进程不会被终止,它们只会成为孤立进程">

下面的程序按您的预期工作,在第一个进程完成后优雅地退出第二个进程。(我将"foo.py"重命名为useless.py,将"bar.py"改名为useful.py,并做了一些小的更改,以便在我的计算机上运行它。(

import subprocess
import os
def run_script(name):
s = os.path.join(r"c:pyproj310so", name)
return subprocess.Popen(["py", s])
if __name__ == "__main__":
useless_p = run_script("useless.py")
useful_p = run_script("useful.py")

useful_p.wait() # Wait for useful script to finish executing
useless_p.kill() # Kill loading animation

您不能使用subprocess.run((来启动新进程,因为该函数将阻塞主脚本,直到进程完成。所以我用了波本。此外,我还将运行的代码放在if __name__ == "__main__"下,这是一种很好的做法(在Windows上可能是必要的(。

最新更新