繁体   English   中英

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

[英]How to kill all Pool workers in multiprocess?

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

我有一个包含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,))

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

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

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

输出:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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

你不能这样做。

即使您在i == 20时能够结束所有进程,也无法确定只打印了20个数字,因为您的进程将以非确定性顺序执行。

如果您只想运行20个进程,则需要从主进程(即控制循环)进行管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM