2012-03-24 40 views
5

複数のファイルを並列にダウンロードするダウンローダ機能があります。 私はmultiprocessing.Pool.map_asyncを使用して、同じファイルの異なるチャンクをダウンロードします。 ダウンロードのステータスバーを表示したいと思います。このため、私は既にダウンロードされた合計バイト数を知る必要があります(total_bytes_dl)。プロセス間で変数を共有する

pool = multiprocessing.Pool(processes) 
    mapObj = pool.map_async(f, args) 

    while not mapObj.ready(): 
     status = r"%.2f MB/%.2f MB" % (total_bytes_dl/1024.0/1024.0, filesize/1024.0/1024.0,) 
     status = status + chr(8)*(len(status)+1) 
     print status, 
     time.sleep(0.5) 

これらすべてのプロセスと主要プロセス間で共有される変数なので、すべてのプロセスがちょうどダウンロードしたバイトの量を追加することができますを設定する方法はありますか?あなただけのバイトはそれが何をすべきダウンロードしたい場合は

答えて

3

ソリューションは、新しいプロセスをintilizeと共有ctypesの値を渡すことだった:彼らは労働者に、この変数を渡し

que = multiprocessing.Manager().Queue() 

、および:

from ctypes import c_int 
import dummy 

shared_bytes_var = multiprocessing.Value(c_int) 

def Func(...): 
    .... 
    pool = multiprocessing.Pool(initializer=_initProcess,initargs=(shared_bytes_var,)) 
    .... 

def _initProcess(x): 
    dummy.shared_bytes_var = x 
1

確かに、あなたは、共有メモリ内の共有​​値を使用することができます。各ワーカーに関連する値を渡すと、呼び出したプロセスはそのワーカーにアクセスできます。

は、以下を参照してください。 http://docs.python.org/library/multiprocessing.html#shared-ctypes-objects

+2

ctypes共有オブジェクトをマップすることはできません: 'RuntimeError:同期されたオブジェクトは、継承を介してプロセス間でのみ共有する必要があります' – iTayb

0

あなたは労働者が上のステータスデータを送信するために使用できることをマルチキューオブジェクトを使用することができます。メインプロセスは、キューからステータスエントリを読み取り、ステータスをそれに応じて更新する必要があります。

1

は次のように割り当てられたキューオブジェクトを使用しますque.put(bytes)〜 は、最後のレポート以降にダウンロードした分を定期的に報告できます。あなたは そしてちょうどすべての着信レポートにキューのサイズをチェックして、引っ張る:

downloaded = 0 
while not mapObj.ready(): 
    for _ in range(q.qsize()): 
     downloaded += q.get() 
    print downloaded, r"bytes downloaded\r", 
    time.sleep(0.5) 

注:モジュールはまた、法multiprocessing.Queue()を提供が、それは完全にmultiprocessing.Manager().Queue()と同等ではありません。 this questionと答えを参照してください。

関連する問題