Python 中多处理模块的池和队列问题

Issue with Pool and Queue of multiprocessing module in Python

我是 Python 的多处理新手,我写了下面的小脚本:

import multiprocessing
import os

def task(queue):
    print(100)

def run(pool):
    queue = multiprocessing.Queue()
    for i in range(os.cpu_count()):
        pool.apply_async(task, args=(queue, ))

if __name__ == '__main__':
    multiprocessing.freeze_support()
    pool = multiprocessing.Pool()
    run(pool)
    pool.close()
    pool.join()

我想知道为什么不执行task()方法,运行这个脚本后没有输出。谁能帮帮我?

它是 运行,但它在主线程外因错误而死亡,因此您看不到错误。出于这个原因,.get() 异步调用的结果总是好的,即使您不关心结果:.get() 会引发否则不可见的错误。

例如,像这样更改循环:

tasks = []
for i in range(os.cpu_count()):
    tasks.append(pool.apply_async(task, args=(queue,)))
for t in tasks:
    t.get()

然后新的t.get()会爆炸,结束于:

RuntimeError: Queue objects should only be shared between processes through inheritance

简而言之,不支持将 Queue 对象传递给 Pool 方法。

但是您可以将它们传递给multiprocessing.Process(),或者Pool初始化函数。例如,这是执行后者的一种方法:

import multiprocessing
import os

def pool_init(q):
    global queue # make queue global in workers
    queue = q

def task():
    # can use `queue` here if you like
    print(100)

def run(pool):
    tasks = []
    for i in range(os.cpu_count()):
        tasks.append(pool.apply_async(task))
    for t in tasks:
        t.get()

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    pool = multiprocessing.Pool(initializer=pool_init, initargs=(queue,))
    run(pool)
    pool.close()
    pool.join()

在 Linux-y 系统上,您可以 - 正如原始错误消息所建议的那样 - 使用进程继承代替(但在 Windows 上这是不可能的)。