多进程队列 vs. 进程池

13

我正在努力弄清楚在使用上multiprocessing.Poolmultiprocessing.Queue之间的区别。

为了帮助,这段代码是我尝试做的一个基本示例。

def update():
    def _hold(url):
        soup = BeautifulSoup(url)
        return soup
    def _queue(url):
        soup = BeautifulSoup(url)
        li = [l for l in soup.find('li')]
        return True if li else False

    url = 'www.ur_url_here.org'
    _hold(url)
    _queue(url)

我正试图同时运行_hold()_queue()。我不想让它们相互通信,所以不需要使用Pipe。每隔5秒钟调用update()

我真的无法理解创建工作进程池和创建函数队列之间的区别。有人能帮助我吗?

实际的_hold()_queue()函数比示例要复杂得多,因此并发执行确实是必需的,我只是认为这个示例足以提出问题。

1个回答

16

PoolQueue属于两个不同的抽象级别。

Worker池是一种并发设计范例,旨在抽象出许多在使用进程和队列时您需要自己实现的逻辑。

multiprocessing.Pool实际上在内部使用一个Queue进行操作。

如果您的问题足够简单,您可以轻松地依赖于Pool。 在更复杂的情况下,您可能需要自己处理进程和队列。

对于您的特定示例,以下代码应该能解决问题。

def hold(url):
    ...
    return soup

def queue(url):
    ...
    return bool(li)

def update(url):
    with multiprocessing.Pool(2) as pool:
        hold_job = pool.apply_async(hold, args=[url])
        queue_job = pool.apply_async(queue, args=[url])

        # block until hold_job is done
        soup = hold_job.get()
        # block until queue_job is done
        li = queue_job.get()

我也建议您查看concurrent.futures模块。正如名称所示,这是Python中Pool of Workers范例的未来证明实现。

您可以轻松使用该库重新编写上面的示例,因为真正更改的只是API名称。


谢谢,这正是我在寻找的,我不知道我可以多次调用apply_async()。我会研究一下futures - aseylys

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