【问题标题】:Fix jumping of multiple progress bars (tqdm) in python multiprocessing修复python多处理中多个进度条(tqdm)的跳转
【发布时间】:2019-06-19 10:33:32
【问题描述】:

我想为一系列输入参数 (L) 并行化一个任务 (progresser())。每个任务的进度应通过终端中的单独进度条进行监控。我正在为进度条使用tqdm 包。以下代码在我的 Mac 上最多可用于 23 个进度条(L = list(range(23)) 及以下),但会产生从 L = list(range(24)) 开始的进度条的混乱跳跃。有谁知道如何解决这个问题?

from time import sleep
import random
from tqdm import tqdm
from multiprocessing import Pool, freeze_support, RLock

L = list(range(24)) # works until 23, breaks starting at 24

def progresser(n):
    text = f'#{n}'

    sampling_counts = 10
    with tqdm(total=sampling_counts, desc=text, position=n+1) as pbar:
        for i in range(sampling_counts):
            sleep(random.uniform(0, 1))
            pbar.update(1)

if __name__ == '__main__':
    freeze_support()

    p = Pool(processes=None,
                initargs=(RLock(),), initializer=tqdm.set_lock
                )
    p.map(progresser, L)
    print('\n' * (len(L) + 1))

作为一般情况下的示例,我在下面提供了L = list(range(16)) 的屏幕截图。

版本:python==3.7.3tqdm==4.32.1

【问题讨论】:

    标签: python terminal multiprocessing progress-bar tqdm


    【解决方案1】:

    当我将大小设置为 30 时,我没有任何跳跃。也许你有更多的处理器,可以让更多的工人在运行。

    但是,如果 n 变大,由于块大小的性质,您将开始看到跳跃。

    p.map 会将您的输入分成块大小并给每个进程一个块。所以随着n 变大,你的块大小也会变大,你的.......是的position (pos=n+1)!

    注意:虽然地图保留了结果的顺序返回。它的计算顺序是任意的。

    随着n 变大,我建议使用处理器 ID 作为查看每个进程进度的位置。

    from time import sleep
    import random
    from tqdm import tqdm
    from multiprocessing import Pool, freeze_support, RLock
    from multiprocessing import current_process
    
    
    def progresser(n):
        text = f'#{n}'
        sampling_counts = 10
        current = current_process()
        pos = current._identity[0]-1
    
        with tqdm(total=sampling_counts, desc=text, position=pos) as pbar:
            for i in range(sampling_counts):
                sleep(random.uniform(0, 1))
                pbar.update(1)
    
    if __name__ == '__main__':
        freeze_support()
        L = list(range(30)) # works until 23, breaks starting at 24
        # p = Pool(processes=None,
        #         initargs=(RLock(),), initializer=tqdm.set_lock
        #         )
        with Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),)) as p: 
            p.map(progresser, L)
            print('\n' * (len(L) + 1))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-13
      • 2017-06-14
      • 2021-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多