2017-03-28 125 views
4

我試圖通過多個進程使用tqdm。行爲並不如預期。我認爲重點在於pbar的值不會通過這些進程更新。那麼如何處理這個問題呢?我也嘗試用Value手動更新pbar.n,但仍然失敗。看起來tqdm不支持更新值並手動呈現。如何在python中通過多進程使用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)) 

回答

4

一般來說,每個進程都有自己的數據,與其他進程無關。 產生一個新進程(在Unix上調用os.fork)創建當前進程的副本。每個進程都會獲取其全部全局值的副本(如 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() 
+0

它運作良好,除了塊永遠在'proc.join()'。我認爲可以通過在'proc.join()'之前添加'q.put(None)'來完成偵聽器進程。非常感謝。 – Sraw

+0

@Sraw:哎呀,你說得很對。感謝您的更正。 – unutbu

相關問題