[英]join() output from multiprocessing when using tqdm for progress bar
我正在使用与此示例类似的构造来并行运行我的处理以及由tqdm
提供的进度条...
from multiprocessing import Pool
import time
from tqdm import *
def _foo(my_number):
square = my_number * my_number
return square
if __name__ == '__main__':
with Pool(processes=2) as p:
max_ = 30
with tqdm(total=max_) as pbar:
for _ in p.imap_unordered(_foo, range(0, max_)):
pbar.update()
results = p.join() ## My attempt to combine results
虽然results
始终是NoneType
,但我无法弄清楚如何组合我的结果。 我知道with ...:
将在完成时自动关闭它正在使用的内容。
我试过用以下方法去掉外部with:
if __name__ == '__main__':
max_ = 10
p = Pool(processes=8)
with tqdm(total=max_) as pbar:
for _ in p.imap_unordered(_foo, range(0, max_)):
pbar.update()
p.close()
results = p.join()
print(f"Results : {results}")
对如何join()
我的结果感到困惑?
您对p.join()
的调用只是等待所有池进程结束并返回None
。 此调用实际上是不必要的,因为您将池用作上下文管理器,即您已将with Pool(processes=2) as p:
)。 当该块终止时, p.terminate()
进行隐式调用,该调用会立即终止池进程和任何可能正在运行或排队运行的任务(在您的情况下没有)。
实际上,它是对p.imap_unordered
调用返回的迭代器进行迭代,该迭代器从您的工作函数_foo
返回每个返回值。 但是由于您使用的是imap_unordered
方法,因此返回的结果可能不是按提交顺序排列的。 换句话说,您不能假设返回值将连续为 0、1、...、4、9 等。有很多方法可以处理这个问题,例如让您的工作函数返回原始参数以及平方值:
from multiprocessing import Pool
import time
from tqdm import *
def _foo(my_number):
square = my_number * my_number
return my_number, square # return the argunent along with the result
if __name__ == '__main__':
with Pool(processes=2) as p:
max_ = 30
results = [None] * 30; # preallocate the resulys array
with tqdm(total=max_) as pbar:
for x, result in p.imap_unordered(_foo, range(0, max_)):
results[x] = result
pbar.update()
print(results)
第二种方法是不使用imap_unordered
,而是使用带有回调函数的apply_async
。 这样做的缺点是,对于大型可迭代对象,您无法像使用imap_unordered
那样指定chunksize参数:
from multiprocessing import Pool
import time
from tqdm import *
def _foo(my_number):
square = my_number * my_number
return square
if __name__ == '__main__':
def my_callback(_): # ignore result
pbar.update() # update progress bar when a result is produced
with Pool(processes=2) as p:
max_ = 30
with tqdm(total=max_) as pbar:
async_results = [p.apply_async(_foo, (x,), callback=my_callback) for x in range(0, max_)]
# wait for all tasks to complete:
p.close()
p.join()
results = [async_result.get() for async_result in async_results]
print(results)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.