Как использовать tqdm через мультипроцесс в питоне?
Я пытаюсь использовать tqdm
через несколько процессов. И поведение не так, как ожидалось. Я думаю, дело в том, что ценность pbar
не обновляется через процессы. Так как бороться с этой проблемой? Я также пытался использовать Value
обновлять pbar.n
вручную, но все равно не удалось. Похоже на то tqdm
не поддерживает обновление значения и визуализации вручную.
def test(lock, pbar):
for i in range(10000):
sleep(0.1)
lock.acquire()
pbar.update()
lock.release()
pbar = tqdm(total = 10000)
lock = Lock()
for i in range(5):
Process(target = test, args = (lock, pbar))
1 ответ
Как правило, каждый процесс имеет свои собственные данные, независимые от любого другого процесса. Порождение нового процесса (который вызывает os.fork
в Unix) создает копию текущего процесса. Каждый процесс получает свою собственную копию всех глобальных значений (таких какpbar
). Глобальные переменные каждого процесса могут иметь те же имена, что и переменные в других процессах, но каждый может иметь независимое значение.
В вашем случае это выглядит так, как будто вы хотите только один pbar
существовать, и все призывы кupdate
следует обновить это pbar
, Так создай pbar
только в одном процессе, и использовать Queue
отправить сигналы этому процессу для обновления pbar
:
import multiprocessing as mp
SENTINEL = 1
def test(q):
for i in range(10000):
sleep(0.1)
q.put(SENTINEL)
def listener(q):
pbar = tqdm(total = 10000)
for item in iter(q.get, None):
pbar.update()
if __name__ == '__main__':
q = mp.Queue()
proc = mp.Process(target=listener, args=(q,))
proc.start()
workers = [mp.Process(target=test, args=(q,)) for i in range(5)]
for worker in workers:
worker.start()
for worker in workers:
worker.join()
q.put(None)
proc.join()