0

Я пишу эту программу, которая одновременно загружает несколько файлов с использованием потоков и сообщает о прогрессе для каждого файла на экране. Я использую один поток, чтобы загрузить каждый файл. Это не проблема:Python Threading: многострочный отчет о проделанной работе

for file_url, filename in zip(file_urls, filenames): 
    th = Thread(target=download_file, args=(file_url, filename)) 
    threads.append(th) 
    th.start() 

for thread in threads: 
    thread.join() 

Проблема заключается в том, я не знаю, в любом случае, что я могу напечатать каждый отчет о ходе файла на экран, который будет выглядеть следующим образом:

"Downloading 'example1.zip': 54366 bytes of 2240799 70.7%" 
    "Downloading 'example2.zip': 31712 bytes of 1924639 64.7%" 
    "Downloading 'example3.zip': 21712 bytes of 3224979 34.7%" 

Следующий фрагмент кода для один доклад о ходе работы линии:

def chunk_report(bytes_so_far, total_size, filename): 

    percent = float(bytes_so_far)/total_size 
    percent = round(percent * 100, 2) 
    print "Downloading '{0}': {1} of {2} {3:3.2g}% \r".format(filename, 
             bytes_so_far, total_size, percent), 

и результат будет выглядеть следующим образом:

"Downloading 'example2.zip': 31712 bytes of 1924639 64.7%" 

каждый раз, когда поток вызывает эту функцию, он обновляет экран для файла, который загружается нитью.

Итак, вопрос в том, как напечатать многострочный отчет о ходе работы, подобный тому, который я проиллюстрировал выше в python?

Заранее спасибо.

ответ

0

Я хотел бы использовать очереди, чтобы сообщить о прогрессе в отчетную тему:

  1. Создание очереди
  2. нереста каждой загрузки нити прохождения очереди в качестве аргумента
  3. ли каждый скачивает put прогресс сообщений в очередь
  4. Создайте поток отчетов, который считывает сообщения о ходе выполнения из очереди и обновляет отображение

Моделируемый пример:

import threading 
import time 
import random 
import Queue 
import sys 

# a downloading thread 
def worker(path, total, q): 
    size = 0 
    while size < total: 
    dt = random.randint(1,3) 
    time.sleep(dt) 
    ds = random.randint(1,5) 
    size = size + ds 
    if size > total: size = total 
    q.put(("update", path, total, size)) 
    q.put(("done", path)) 

# the reporting thread 
def reporter(q, nworkers): 
    status = {} 
    while nworkers > 0: 
    msg = q.get() 
    if msg[0] == "update": 
     path, total, size = msg[1:] 
     status[path] = (total, size) 
     # update the screen here 
     show_progress(status) 
    elif msg[0] == "done": 
     nworkers = nworkers - 1 
    print "" 

def show_progress(status): 
    line = "" 
    for path in status: 
    (total, size) = status[path] 
    line = line + "%s: %3d/%d " % (path, size,total) 
    sys.stdout.write("\r"+line) 
    sys.stdout.flush() 

def main(): 
    q = Queue.Queue() 
    w1 = threading.Thread(target = worker, args = ("abc", 30, q)) 
    w2 = threading.Thread(target = worker, args = ("foobar", 25, q)) 
    w3 = threading.Thread(target = worker, args = ("bazquux", 16, q)) 
    r = threading.Thread(target = reporter, args = (q, 3)) 
    for t in [w1,w2,w3,r]: t.start() 
    for t in [w1,w2,w3,r]: t.join() 

main() 
Смежные вопросы