我正在编写此程序,该程序使用线程同时下载多个文件,并在屏幕上报告每个文件的进度。
我正在使用一个不同的线程来下载每个文件。没问题:

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中说明的那样?

提前致谢。

最佳答案

我将使用Queue向进度报告线程报告进度:


创建一个队列
生成每个通过Queue作为参数的下载线程
让每个下载put进度消息到队列
生成报告线程,该线程从队列中读取进度消息并更新显示


一个模拟的例子:

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

关于python - Python线程:多行进度报告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28057445/

10-15 17:46