[英]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.