如何从python中的多处理过程中退出主程序

How to exit a main program from the Multiprocessing Process in python

我使用multiprocessing.process生成3个进程并等待它们完成。 如果其中一个失败,那么我想停止所有其他进程以及主程序。 但是当我使用sys.exit时,执行只是停止进程而不是主程序。 这是代码的片段。

1
2
3
4
5
6
7
8
9
proc1=process(function1)
proc2=process(function2)
proc3=process(function3)
proc1.start
proc2.start
proc3.start
proc1.join
proc2.join
proc3.join



我在函数1,2和3中运行一些任务。我在每个函数中都有一个条件来检查任务的返回码,如果返回码不成功,那么我想停止proc1,proc2和proc3并停止执行 主程序。 当我在函数内部执行sys.exit时,它刚刚从该进程中出来而不是主程序。


为此,您需要在工作进程和主进程之间进行通信。可能最简单的方法是使用multiprocessing.Event

在开始进程之前,创建一对multiprocessing.Event。给他们有意义的名字,如stop_mainstop_workers。为了便于携带,应该将这些Event添加到为Process目标给出的参数中。

当工作进程希望主程序退出时,它应该调用stop_main.set()。工作进程也应定期调用stop_workers.is_set(),并在返回True时退出。

在主进程启动所有工作程序之后,它应该继续轮询stop_main.is_set()。当返回True时,它应该调用stop_workers.set()join工作者并退出。

更新:

编辑使其更短,并希望它在ms-windows上工作。

一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import multiprocessing as mp
import time


def worker(num, sw, sm):
    if num == 5:
        print('This is worker', num)
        time.sleep(1)
        print('Worker', num, 'signalling main program to quit')
        sm.set()
    while not sw.is_set():
        print('This is worker', num)
        time.sleep(0.7)
    else:
        print('Worker', num, 'signing off..')


if __name__ == '__main__':
    stop_worker = mp.Event()
    stop_main = mp.Event()

    workers = [mp.Process(target=worker, args=(n, stop_worker, stop_main))
               for n in range(1, 6)]
    for w in workers:
        w.start()
    while not stop_main.is_set():
        time.sleep(1)
    print('MAIN: Received stop event')
    print('MAIN: Sending stop event to workers')
    stop_worker.set()
    for c, w in enumerate(workers, start=1):
        w.join()
        print('worker', c, 'joined')

它运行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
This is worker 1
This is worker 2
This is worker 3
This is worker 4
This is worker 5
This is worker 2
This is worker 3
This is worker 1
This is worker 4
Worker 5 signalling main program to quit
This is worker 5
This is worker 2
This is worker 3
This is worker 1
This is worker 4
This is worker 5
MAIN: Received stop event
MAIN: Sending stop event to workers
Worker 3 signing off..
Worker 1 signing off..
Worker 2 signing off..
worker 1 joined
worker 2 joined
worker 3 joined
Worker 4 signing off..
worker 4 joined
Worker 5 signing off..
worker 5 joined


这是一个解决方案。一旦__main__退出,您将失去与已启动流程的所有通信,但这对于我的matplotlib用例是可以的。只需关闭窗口,或者如您所述,关闭外壳。

此处详细介绍了示例脚本。