2017-03-28 58 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)の独自のコピーを取得します。各プロセスのグローバル変数は、他のプロセスで変数 と同じ名前を共有していても、それぞれ独立した値を保持できます。

あなたのケースでは、あなただけの1 pbarが存在したいように見えます、と updateへのすべての呼び出しは、その1つのpbarを更新する必要があります。だから、一つのプロセスだけで をpbarを作成し、pbarを更新するために、そのプロセスにシグナルを送信するためにQueueを使用します。それは、() `` proc.joinで永遠にブロックを除いてうまく機能

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()'の前に 'q.put(None)'を追加して、リスナープロセスを終了することで解決できると思います。どうもありがとう。 – Sraw

+0

@Sraw:おっと、あなたは大丈夫です。訂正してくれてありがとう。 – unutbu

関連する問題