我是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()方法,并且在运行此脚本后没有输出。有谁可以帮助我?
答案 0 :(得分:2)
它正在运行,但它在主线程外部出现错误而死亡,因此您没有看到错误。因此,.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上是不可能的)。