我想针对一系列输入参数(progresser()
)并行化任务(L
)。每个任务的进度应通过终端中的单独进度条进行监控。我正在使用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.3
,tqdm==4.32.1
当将大小设置为30时,我没有任何跳跃。也许您有更多的处理器,并且可以有更多的工人在运行。
但是,由于块大小的性质,如果n变大,您将开始看到跳跃。
即p.map
将把您的输入分成块大小,并为每个进程分配一个块。因此,随着n
变大,您的块大小也将增加,.. yup position
(pos = n + 1)也将变大!
注意:尽管地图保留结果的顺序返回。其computed的顺序是任意的。
随着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))