并行进程覆盖进度条 (tqdm)

GRo*_*tar 5 parallel-processing concurrency python-3.x tqdm

我正在用 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)
Run Code Online (Sandbox Code Playgroud)

进度条确实会相应地更新,但由于多个进程运行上面的代码,每个进程都会覆盖控制台上的进度条,如下面的屏幕截图所示。

在此处输入图片说明

完成后,控制台正确显示完成的进度条:

在此处输入图片说明

我的目标是让进度条更新而不会相互覆盖。有没有办法实现这一目标?

一个可能的解决方案是只在需要最长的进程上显示进度条(我事先知道哪个是),但最好的情况是根据第二张图片为每个进程更新一个。

所有解决方案在线地址multiprocess.Pool,但我不打算改变我的架构,因为我可以充分利用multiprocess.Process.

小智 8

要在不覆盖的情况下进行更新,您需要使用positiontqdm的参数,您可以在此处找到该参数。这里,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)
Run Code Online (Sandbox Code Playgroud)