如何提前终止Python多进程池

3

我最近开始研究multiprocessing模块,并发现pool.map函数非常有用,可以快速解析大型数组。但是,是否有一种方法可以提前终止进程池呢?比如说,我有一个巨大的列表,我想在其中找到一个数字,检查它是否能够被x整除,如果可以,则返回true并提前终止进程池,那么我该如何做呢?为了证明这个概念,我正在尝试从3到无穷大找到质数(以最低效的方式)。以下是一个示例:

import multiprocessing
from functools import partial

finders=multiprocessing.pool(multiprocessing.cpu_count()-1)

def is_devis(x, number):
    if number%x==0:
        return True

if __name__=="__main__":
    Primes=[3, 5, 7, 11, 13, 17, ...]
    x=3
    while True:
        x=x+2
        func=partial(is_devis, x)
        results=finders.map(func, Primes)
        if not (True in results):
            Primes.append(x)

我可能不完全理解多进程池或pool.map函数的工作原理,但据我所知,它会平均分配一个可迭代对象并将其分配给池中的所有工作进程,直到所有进程返回或完成。有没有一种方式可以在一个进程返回值时立即终止池?我已经查看了关于multiprocess.pool的文档,但注意到以下内容:

池内的工作进程通常会在池的工作队列完成后继续存在。

提前感谢!


在使用多进程构建应用程序时,实际应用程序是相关的。如果以质数为例,我会这样做:给出一个最大数字,它将是最后一个被测试的数字。创建一个函数,它接受一个数字并告诉你它是否是质数。将此函数映射到范围内的一系列数字上。因此,结束标准不是“进程返回一个值”,而是预设的最大数字。如果您想获得有关如何构建多进程应用程序的建议,请解释您要实现的目标。 - Mathieu
@Mathieu 谢谢你的建议。目前我没有特定的项目,除了那个例子之外。实际上,我正在把它作为一个项目来完成,只是一种找到尽可能多的质数并观察计算机如何处理它的方法。我还会实现一种保存所有质数到文件的方法。但不幸的是问题仍然存在。是否有可能根据进程的结果在池中间终止池? - BobserLuck
1
同时,还可以参考以下链接:https://stackoverflow.com/questions/37691552/how-to-get-all-pool-apply-async-processes-to-stop-once-any-one-process-has-found/37700081#37700081 - noxdafox
@noxdafox 是的,那正是我在寻找的。稍微调整一下就完美地完成了工作。不确定为什么之前搜索时没有找到这个答案,但还是谢谢! - BobserLuck
1个回答

0
一个天真的方法是设置一个全局标志,当线程找到答案时可以设置该标志。在其他线程中,您可以定期检查该标志,并在设置时终止线程。

请注意,这需要将独立进程“共享”标志,这意味着将其放入Manager对象中或使用共享内存原语。 - torek
我在考虑类似的事情。不幸的是,据我所知,当创建一个新进程时,它会创建一个全新的Python实例,不共享任何全局变量。正如@torek所提到的,您可以通过特定类型的共享内存变量来解决这个问题。我尝试过使用这种方法,但由于pool().map只接受可迭代对象,使用partial函数会引发错误。"RuntimeError: Synchronized objects should only be shared between processes through inheritance" - BobserLuck
1
@BobserLuck:Linux的multiprocess使用fork(),以便子进程继承(复制)父进程的设置,包括Manager对象。Manager对象检测到fork并连接到通信通道以共享更新。共享内存原语在内部更简单,因此更高效,但使用起来更困难。我认为Managers可以在Windows上使用,但我不确定具体细节。 - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接