Как использовать 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()
Другие вопросы по тегам