我正在用Python 3.7编写一个脚本,该脚本使用multiprocessing.Process
(每个内核一个任务)启动多个并行任务。为了跟踪每个过程的进度,我使用了实现进度条的库tqdm
。我的代码如下所示:
with tqdm(total=iterator_size) as progress_bar:
for row in tqdm(batch):
process_batch(batch)
progress_bar.update(1)
确实确实会更新进度条,但是由于有多个进程运行上面的代码,因此每个进程都会覆盖控制台上的进度条,如下面的屏幕快照所示。
完成后,控制台会正确显示完成的进度条:
我的目标是更新进度条,而不会彼此覆盖。有什么办法可以做到这一点?
一种可能的解决方案是仅在需要花费最长时间的过程上显示进度条(我事先知道哪个是哪个),但是最好的情况是为每个过程根据第二个更新一个图片。
所有解决方案的在线地址均为multiprocess.Pool
,但我不打算更改自己的体系结构,因为我可以充分利用multiprocess.Process
。
答案 0 :(得分:1)
要进行更新而不覆盖,您需要使用tqdm的position
参数,您可以找到here。这里,position=0
代表最外面的条,position=1
代表下一个的条,依此类推,其中0和1是在打印进度条之前要跳过的行数,即0表示0行之后的进度条,以及1表示1行之后。由于position
需要跳过的行数,因此需要使用multiprocessing.current_process
(注意:请勿输入pid
号,因为它将在打印前跳过那么多行)
from multiprocessing import current_process
""" Your code Here
Here, the current_process() is the process object
current_process().name gives the name of the process
current_process()._identity gives a tuple of the number of process
"""
current = current_process()
with tqdm(total=iterator_size) as progress_bar:
for row in tqdm(batch, desc=str(current.name),
position=current._identity[0] - 1)):
process_batch(batch)
progress_bar.update(1)
答案 1 :(得分:1)
您可以使用 update
在并行循环中更新进度条def func(x, pbar):
for el in batch:
do_something_with_el(el)
pbar.update(1)
with tqdm(total=len(your_list)) as pbar:
batches = np.array_split(your_list, how_many_batches)
Parallel(n_jobs=-1, prefer='threads')(delayed(func)(batch, pbar)
for batch in batches)
这不会产生很多进度条