简体   繁体   English

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

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

I want to stop all threads from a single worker. 我想阻止来自单个工作者的所有线程。

I have a thread pool with 10 workers: 我有一个包含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,))

My program does not stop and the other processes continue working until all 100 iterations are complete. 我的程序没有停止,其他进程继续工作,直到所有100次迭代完成。 I want to stop the pool entirely from inside the thread that calls sys.exit() . 我想完全从调用sys.exit()的线程内部停止池。 The way it is currently written will only stop the worker that calls sys.exit() . 当前编写的方式只会停止调用sys.exit()的worker。

This isn't working the way you're intending because calling sys.exit() in a worker process will only terminate the worker. 这不是你想要的方式,因为在一个工作进程中调用sys.exit()只会终止worker。 It has no effect on the parent process or the other workers, because they're separate processes and raising SystemExit only affects the current process. 它对父进程或其他工作程序没有影响,因为它们是单独的进程,并且提升SystemExit只会影响当前进程。 You need to send a signal back the parent process to tell it that it should shut down. 您需要向父进程发送一个信号,告诉它应该关闭它。 One way to do this for your use-case would be to use an Event created in a multiprocessing.Manager server: 为您的用例执行此操作的一种方法是使用在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

Output: 输出:

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

As pointed out in Luke's answer, there is a race here: There's no guarantee that all the workers will run in order, so it's possible that myfunction(20, ..) will run prior to myfuntion(19, ..) , for example. 正如卢克的答案所指出的,这里有一场比赛:不能保证所有工人都按顺序运行,所以myfunction(20, ..)可能会在myfuntion(19, ..)之前运行,例如。 It's also possible that other workers after 20 will run before the main process can act on the event being set. 在主进程可以对正在设置的事件采取行动之前, 20之后的其他工作人员也可能会运行。 I reduced the size of the race window by adding the if not event.is_set(): call prior to printing i , but it still exists. 我通过在打印i之前添加if not event.is_set():调用来减小竞赛窗口的大小,但它仍然存在。

You can't do this. 你不能这样做。

Even if you were able to end all of your processes when i == 20 , you couldn't be sure that only 20 numbers were printed because your processes will execute in a non-deterministic order. 即使您在i == 20时能够结束所有进程,也无法确定只打印了20个数字,因为您的进程将以非确定性顺序执行。

If you want to only run 20 processes, then you need to manage this from your master process (ie. your control loop). 如果您只想运行20个进程,则需要从主进程(即控制循环)进行管理。

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

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