在Python中反转ProcessPoolExecutor

时间:2017-12-19 23:55:05

标签: python multiprocessing

这与我正在努力解决的earlier problem有关。基本上我需要ProcessPoolExecutor的逆设计,其中我有很多查询过程和一个工人,它可以批量计算和发回结果。

使用一个共享队列轻松发送工作项,但我仍然没有一个很好的解决方案,可以将所有结果发送回正确流程的正确线程。

1 个答案:

答案 0 :(得分:1)

我认为每个查询过程都有一个单独的multiprocessing.pipe是最有意义的。工作进程等待任何管道上的可用项目,并将其出列并处理它,跟踪它来自哪个管道。当它返回数据时,它会将结果提供给正确的管道。

这是一个简单的例子:

#!/usr/bin/env python3

import multiprocessing as mp

def worker(pipes):
    quit = [False] * len(pipes)
    results = [''] * len(pipes)

    # Wait for all workers to send None before quitting
    while not all(quit):
        ready = mp.connection.wait(pipes)
        for pipe in ready:

            # Get index of query proc's pipe
            i = pipes.index(pipe)

            # Receive and "process"
            obj = pipe.recv()
            if obj is None:
                quit[i] = True
                continue
            result = str(obj)
            results[i] += result

            # Send back to query proc
            pipes[i].send(result)
    print(results)


def query(pipe):
    for i in 'do some work':
        pipe.send(i)
        assert pipe.recv() == i
    pipe.send(None) # Send sentinel

if __name__ == '__main__':
    nquery_procs = 8
    work_pipes, query_pipes = zip(*(mp.Pipe() for _ in range(nquery_procs)))

    query_procs = [mp.Process(target=query, args=(pipe,)) for pipe in query_pipes]
    for p in query_procs:
        p.start()
    worker(work_pipes)
    for p in query_procs:
        p.join()

或者,您可以为每个查询过程提供一个ID号(可能只是它的管道索引),任何请求都必须是(id_num, data)的元组。这只是绕过每个循环执行pipes.index(pipe)的工作进程,所以我不确定它会给你多少钱。