Python多处理,池映射 - 取消所有正在运行的进程(如果有),返回所需的结果

时间:2016-09-10 18:24:15

标签: python dictionary multiprocessing pool

给出以下Python代码:

import multiprocessing

def unique(somelist):
    return len(set(somelist)) == len(somelist)


if __name__ == '__main__':
    somelist = [[1,2,3,4,5,6,7,8,9,10,11,12,13,2], [1,2,3,4,5], [1,2,3,4,5,6,7,8,9,1], [0,1,5,1]]

    pool = multiprocessing.Pool()
    reslist = pool.map(unique, somelist)
    pool.close()
    pool.join()
    print "Done!"

    print reslist

现在想象一下,这个玩具示例中的整数列表非常长,我想在这里实现的是:如果某个列表中的某个列表返回True,则终止所有正在运行的进程。

这导致了两个问题(可能还有更多我没想过的问题):

  • 如果其他进程正在运行,我怎样才能从已完成的进程中“读取”/“侦听”结果?如果是一个进程正在处理来自某个列表的[1,2,3,4,5],并且在所有其他进程之前完成,如何在此刻读出该进程的结果?

  • 鉴于在其他正在运行的情况下可以“读取”已完成进程的结果的情况:如何将此结果用作终止所有其他正在运行的进程的条件?

    < / LI>

e.g。如果一个进程已经完成并返回True,我如何使用它作为终止所有其他(仍然)正在运行的进程的条件?

提前感谢您提供任何提示 丹

2 个答案:

答案 0 :(得分:5)

使用pool.imap_unordered按照他们出现的顺序查看结果。

reslist = pool.imap_unordered(unique, somelist)
pool.close()
for res in reslist:
    if res:  # or set other condition here
        pool.terminate()
        break
pool.join()

您可以迭代主进程中的imap重新列表,同时池进程仍在生成结果。

答案 1 :(得分:1)

没有花哨的IPC(进程间通信)技巧,最简单的方法是使用带有回调函数的Pool方法。回调在主程序中运行(在multiprocessing创建的线程中),并在每个结果可用时使用。当回调看到您喜欢的结果时,它可以终止Pool。例如,

import multiprocessing as mp

def worker(i):
    from time import sleep
    sleep(i)
    return i, (i == 5)

def callback(t):
    i, quit = t
    result[i] = quit
    if quit:
        pool.terminate()

if __name__ == "__main__":
    N = 50
    pool = mp.Pool()
    result = [None] * N
    for i in range(N):
        pool.apply_async(func=worker, args=(i,), callback=callback)
    pool.close()
    pool.join()
    print(result)

几乎可以肯定显示以下内容(操作系统调度变幻莫测可能允许使用另一个或两个输入):

[False, False, False, False, False, True, None, None, None, None,
 None, None, None, None, None, None, None, None, None, None,
 None, None, None, None, None, None, None, None, None, None,
 None, None, None, None, None, None, None, None, None, None,
 None, None, None, None, None, None, None, None, None, None]