如何在多进程中杀死所有池工作者?

N3T*_*C4t 7 python multithreading multiprocessing kill-process

我想阻止来自单个工作者的所有线程.

我有一个包含10名工人的线程池:

def myfunction(i):
    print(i) 
    if (i == 20):
        sys.exit()

p = multiprocessing.Pool(10, init_worker) 

for i in range(100):
    p.apply_async(myfunction, (i,))
Run Code Online (Sandbox Code Playgroud)

我的程序没有停止,其他进程继续工作,直到所有100次迭代完成.我想完全从调用的线程内部停止池sys.exit().它当前编写的方式只会阻止调用的工作者sys.exit().

dan*_*ano 15

这不是你想要的方式,因为sys.exit()在一个工作进程中调用只会终止worker.它对父进程或其他工作没有影响,因为它们是单独的进程,并且SystemExit只会影响当前进程.您需要向父进程发送一个信号,告诉它应该关闭它.为您的用例执行此操作的一种方法是使用Eventmultiprocessing.Manager服务器中创建的:

import multiprocessing

def myfunction(i, event):
    if not event.is_set():
        print i 
    if i == 20:
        event.set()

if __name__ == "__main__":
    p= multiprocessing.Pool(10) 
    m = multiprocessing.Manager()
    event = m.Event()
    for i in range(100):
        p.apply_async(myfunction , (i, event))
    p.close()

    event.wait()  # We'll block here until a worker calls `event.set()`
    p.terminate() # Terminate all processes in the Pool
Run Code Online (Sandbox Code Playgroud)

输出:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Run Code Online (Sandbox Code Playgroud)

正如卢克的回答所指出的那样,这里有一场竞赛:不能保证所有工人都按顺序运行,所以有可能myfunction(20, ..)会在之前运行myfuntion(19, ..),例如.之后其他工作人员也可能20在主进程之前运行,可以对正在设置的事件采取行动.我通过if not event.is_set():在打印之前添加调用来缩小竞赛窗口的大小i,但它仍然存在.