2014-09-26 107 views
6

我想停止单个工作人员的所有线程。如何杀死多进程中的所有Pool worker?

我有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()的员工。

回答

11

这不符合你的意图,因为在工作进程中调用sys.exit()只会终止工作人员。它对父流程或其他员工没有影响,因为他们是单独的流程,并且只会影响当前流程。您需要向父进程发回一个信号,告诉它它应该关闭。为您的使用情况做的一个方法是使用在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():呼叫,我缩小了比赛窗口的大小,但它仍然存在。

+1

非常感谢你+1 – N3TC4t 2014-09-26 22:21:38

+0

以上代码中的变量池是什么? – 2017-11-02 08:28:24

+0

@RajanChaudan一个错字!我现在修好了。 – dano 2017-11-02 12:10:50

1

你不能这样做。

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

如果你只想运行20个进程,那么你需要从你的主进程(即你的控制循环)管理这个进程。