8

マルチプロセッシング ダウンローダーを実装しました。端末の別の部分で自動的に更新できるステータスバー(完了率、ダウンロード速度)を印刷するにはどうすればよいですか。

このような:

    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 は Process クラスを継承し、ダウンロード メソッドをトリガーします。

URL を格納するために queue を使用します。これが開始プロセスです

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

1 に答える 1

23

以下は、マルチプロセッシングとマルチスレッドの両方を実装したデモです。どちらかを試すには、コードの上部にある import 行のコメントを外してください。1 行にプログレス バーがある場合は、'\r' を印刷する手法を使用して、カーソルを行の先頭に戻すことができます。しかし、複数行のプログレス バーが必要な場合は、少し工夫する必要があります。プログレスバーを印刷するたびに画面をクリアしました。Python での Unix に関する記事のコンソール出力を確認してください。以下のコードを作成するのに大いに役立ちました。彼は両方のテクニックを示しています。Python 標準ライブラリの一部である curses ライブラリを試すこともできます。質問複数行の進行状況バー同様のことを尋ねます。メイン スレッド/プロセスは、作業を行う子スレッドを生成し、キューを使用して進行状況をメイン スレッドに伝えます。プロセス/スレッド間通信にキューを使用することを強くお勧めします。次に、メイン スレッドは進行状況を表示し、すべての子スレッドが実行を終了するのを待ってから終了します。

コード

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()

デモ

ここに画像の説明を入力

于 2012-12-19T06:41:18.640 に答える