2012-12-19 35 views
8

Tôi đã triển khai trình tải xuống đa xử lý. Làm cách nào để in thanh trạng thái (tỷ lệ hoàn thành, tốc độ tải xuống) có thể tự động làm mới ở một phần khác trên thiết bị đầu cuối.In lại làm mới động của đa xử lý hoặc đa luồng trong Python

Như thế này:

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

mã:

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 kế thừa lớp Process và kích hoạt các phương pháp tải về.

Tôi sử dụng hàng đợi để lưu trữ url. Dưới đây là quá trình

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

Ông có thể cũng cung cấp đến mã cho chúng tôi để cải thiện? –

+0

http://excess.org/urwid/ có thể giúp bạn, nhưng chỉ về việc cung cấp cho bạn các widget có vị trí đẹp cho công việc. Bạn sẽ cần phải có một 'đầu' quản lý tất cả các danh sách bạn đang hiển thị đang chạy trong quy trình tổng thể. Nó rất có thể dễ dàng hơn để làm một trang web tho. – synthesizerpatel

+0

@MarkGarcia Đã cập nhật –

Trả lời

21

Dưới đây bắt đầu là một bản demo mà đã thực hiện cả hai đa xử lý và đa luồng. Để thử một hoặc khác chỉ cần bỏ ghi chú các dòng nhập ở đầu mã. Nếu bạn có thanh tiến trình trên một dòng thì bạn có thể sử dụng kỹ thuật mà bạn có in '\ r' để di chuyển con trỏ trở lại đầu dòng. Nhưng nếu bạn muốn có các thanh tiến trình nhiều dòng thì bạn sẽ phải có một chút fancier. Tôi chỉ xóa màn hình mỗi lần tôi muốn in các thanh tiến trình. Hãy xem bài viết console output on Unix in Python nó đã giúp tôi rất nhiều trong việc sản xuất mã dưới đây. Ông cho thấy cả hai kỹ thuật. Bạn cũng có thể cung cấp cho thư viện lời nguyền đó là một phần của thư viện chuẩn python một shot. Câu hỏi Multiline progress bars hỏi một điều tương tự. Chủ đề/quy trình chính sinh ra các chủ đề con thực hiện công việc và truyền đạt tiến trình của chúng trở lại luồng chính bằng cách sử dụng hàng đợi. Tôi khuyên bạn nên sử dụng hàng đợi cho liên lạc/quá trình liên thông. Chủ đề chính sau đó hiển thị tiến độ và chờ cho tất cả trẻ em kết thúc thực hiện trước khi thoát khỏi chính nó.

đang

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

bản demo

enter image description here

+0

Tuyệt đối rực rỡ. Đơn giản hơn nhiều so với quái vật tôi tưởng tượng. Cảm ơn. – Cerin

+0

@Cerin Điều đó hóa ra hầu như luôn luôn là trường hợp với Python :) –

Các vấn đề liên quan