首页 > 解决方案 > 如何在 Python 多进程中在父子之间共享队列

问题描述

我想将任务结果保存到队列中,任务在多个进程中运行。在所有任务运行完成后,从队列中读取结果。

为什么子任务中打印的队列大小是正确的,但在父进程中为0?我也无法在父级中获取队列数据。如何解决这个问题?

Python3中的代码:

import multiprocessing

que = multiprocessing.Queue()

def task(n):
    que.put(n)
    print("Child: queue len is %d" % que.qsize())

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    pool.map(task, range(10))
    print("Parent: queue len is %d" % que.qsize())

输出:

Child: queue len is 1
Child: queue len is 2
Child: queue len is 3
Child: queue len is 4
Child: queue len is 5
Child: queue len is 6
Child: queue len is 7
Child: queue len is 8
Child: queue len is 9
Child: queue len is 10
Parent: queue len is 0    // Why here is not 10??

标签: pythonpython-3.xmultiprocessing

解决方案


当您在 中运行taskpool.map,包含函数的模块task将被导入并task使用您在 中指定的参数调用pool.map

因此,原始队列不会传递给它。当您导入模块(在其他进程中)时,会创建一个新的全局队列。

为了使行为更加明显,我稍微修改了您的示例,以便它产生更多进程:

import multiprocessing
import time

que = multiprocessing.Queue()

def task(n):
    que.put(n)
    print("Child: queue len is %d" % que.qsize())
    time.sleep(0.1)

if __name__ == '__main__':
    pool = multiprocessing.Pool(10)
    pool.map(task, range(10))
    print("Parent: queue len is %d" % que.qsize())

现在它打印:

Child: queue len is 1
Child: queue len is 1
Child: queue len is 2
Child: queue len is 1
Child: queue len is 1
Child: queue len is 1
Child: queue len is 1
Child: queue len is 1
Child: queue len is 1
Child: queue len is 1
Parent: queue len is 0

要共享队列,您必须将其传递给其他进程,但不能通过map. 在其他几个 SO 答案中提供了替代方案,例如

在您的情况下最好的方法取决于您实际尝试对该队列执行的操作。


推荐阅读