2012-12-19 19 views
8

私はマルチプロセッシングダウンローダを実装しました。 ターミナルの別の部分に自動的に更新できるステータスバー(完全な速度、ダウンロード速度)を印刷するにはどうすればいいですか? このようPythonでのマルチプロセッシングまたはマルチスレッドのダイナミックリフレッシュ印刷

499712 [6.79%] 68k/s  // keep refreshing 
    122712 [16.79%] 42k/s // different process/thread 
    99712 [56.32%] 10k/s 

コード:

download(...) 
... 
    f = open(tmp_file_path, 'wb') 
    print "Downloading: %s Bytes: %s" % (self.file_name, self.file_size) 
    file_size_dl = 0 
    block_sz = 8192 
    start_time = time.time() 
    while True: 
     buffer = self.opening.read(block_sz) 
     if not buffer: 
      break 

     file_size_dl += len(buffer) 
     f.write(buffer) 
     end_time = time.time() 
     cost_time = end_time - start_time 
     if cost_time == 0: 
      cost_time = 1 
     status = "\r%10d [%3.2f%%] %3dk/s" % (file_size_dl, 
       file_size_dl * 100./self.file_size, 
       file_size_dl * 100./1024/1024/cost_time) 
     print status, 
     sys.stdout.flush() 
    f.close() 

DownloadProcessプロセスのクラスを継承し、ダウンロード方法をトリガします。

私は、URLを格納するためにキューを使用します。ここに始まるプロセス

... 
    for i in range(3): 
    t = DownloadProcess(queue) 
    t.start() 
    for url in urls: 
     queue.put(url) 
    queue.join() 
+0

はあなたにも私たちが改善するためのコードを来る提供してもらえますか? –

+0

http://excess.org/urwid/が役に立つかもしれませんが、タスクのための優れたウィジェットを提供する点でのみ役に立ちます。マスタープロセスで表示されているすべてのリストを管理する「頭」が必要です。ウェブページを行うほうが簡単でしょう。 – synthesizerpatel

+0

@MarkGarcia更新された –

答えて

21

以下は、マルチプロセッシングとマルチスレッドの両方を実装したデモです。どちらかを試してみると、コードの先頭にあるインポート行のコメントを外すだけです。 1行にプログレスバーがある場合は、 '\ r'を印刷するテクニックを使用して、カーソルを行の先頭に戻すことができます。しかし、複数行のプログレスバーが必要な場合は、少し好きになる必要があります。進行状況バーを印刷するたびに画面をクリアしました。記事console output on Unix in Pythonをチェックすると、以下のコードを作成するのに大いに役立ちました。彼は両方のテクニックを示しています。また、python標準ライブラリの一部であるcursesライブラリにショットを与えることもできます。質問Multiline progress barsも同様のことを尋ねます。メインスレッド/プロセスは、作業を行う子スレッドを生成し、その進行状況をキューを使用してメインスレッドに返信します。プロセス間/スレッド通信にはキューを使用することを強くお勧めします。その後、メインスレッドは進行状況を表示し、すべての子プロセスが終了して自身を終了するのを待ちます。

コード

import time, random, sys, collections 
from multiprocessing import Process as Task, Queue 
#from threading import Thread as Task 
#from Queue import Queue 

def download(status, filename): 
    count = random.randint(5, 30) 
    for i in range(count): 
     status.put([filename, (i+1.0)/count]) 
     time.sleep(0.1) 

def print_progress(progress): 
    sys.stdout.write('\033[2J\033[H') #clear screen 
    for filename, percent in progress.items(): 
     bar = ('=' * int(percent * 20)).ljust(20) 
     percent = int(percent * 100) 
     sys.stdout.write("%s [%s] %s%%\n" % (filename, bar, percent)) 
    sys.stdout.flush() 

def main(): 
    status = Queue() 
    progress = collections.OrderedDict() 
    workers = [] 
    for filename in ['test1.txt', 'test2.txt', 'test3.txt']: 
     child = Task(target=download, args=(status, filename)) 
     child.start() 
     workers.append(child) 
     progress[filename] = 0.0 
    while any(i.is_alive() for i in workers): 
     time.sleep(0.1) 
     while not status.empty(): 
      filename, percent = status.get() 
      progress[filename] = percent 
      print_progress(progress) 
    print 'all downloads complete' 

main() 

デモ

enter image description here

+0

絶対に華麗です。私が想像していた怪物よりずっと簡単です。ありがとう。 – Cerin

+0

@Cerinこれはほとんどの場合、Pythonの場合です。 –

関連する問題