在Python中动态刷新多处理或多线程 [英] Dynamic refresh printing of multiprocessing or multithreading in Python

查看:708
本文介绍了在Python中动态刷新多处理或多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了多处理下载器。
如何打印状态栏(完整的速率,下载速度),可以自动刷新
在终端的不同部分。



像这样:

  499712 [6.79%] 68k / s //保持刷新
122712 [16.79%] 42k / s / /不同流程/线程
99712 [56.32%] 10k / s

代码:

 下载(...)
...
f = open(tmp_file_path,'wb')
print下载:%s字节:%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)
如果不是缓冲区:
break

file_size_dl + = len(buffer)
f.write(buffer)
end_time = time.time()
cost_time = end_time - start_time
如果cost_time == 0:
cost_time = 1
s %td = 10%[%3.2f %%]%3dk / s%(file_size_dl,
file_size_dl * 100. / self.file_size,
file_size_dl * 100. / 1024/1024 / cost_time)
打印状态,
sys.stdout.flush()
f.close()

DownloadProcess继承Process类并触发下载方法。



我使用队列来存储url。这是开始的过程

  ... 
for i in range(3):
t = DownloadProcess队列)
t.start()
在urls中的url:
queue.put(url)
queue.join()


解决方案

下面是一个实现了多处理和多线程的演示。尝试一个或另一个只是取代对代码顶部的导入行的注释。如果您在单行上有进度条,那么您可以使用打印'\r'的技术将光标移回到行的开头。但是如果你想要有多行进度条,那么你将得到一点点爱好者。每当我想打印进度条时,我都清除了屏幕。查看文章控制台输出在Python中的Unix ,它帮助我很大程度上生成下面的代码。他显示了两种技术。您还可以将作为python标准库一部分的诅咒图书馆投放。 多线进度条的问题也是类似的。主线程/进程产生执行工作的子线程,并使用队列将进度回传到主线程。我强烈建议使用队列进行进程间/线程通信。主线程显示进度并等待所有孩子在退出之前终止执行。



代码

 导入时间,随机,sys,集合
从多进程导入进程作为任务,队列
#from线程导入线程作为任务
#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 %% \\\
%(filename,bar,percent )
sys.stdout.flush()

def main():
status = Queue()
progress = collections.OrderedD ict()
workers = []
在['test1.txt','test2.txt','test3.txt']中的文件名:
child = Task(target = args =(status,filename))
child.start()
workers.append(child)
progress [filename] = 0.0
while any(i.is_alive()for我在工作中):
time.sleep(0.1)
而不是status.empty():
文件名,percent = status.get()
进度[filename] =百分比
print_progress(progress)
print'全部下载完成'

main()

演示




I have implemented a multiprocessing downloader. How can I print the status bar (complete rate, download speed) which can refresh automatically in different part on the terminal.

Like this:

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

code:

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 inherits Process class and trigger the download method.

I use queue to store the url. Here is starting process

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

解决方案

Below is a demo that has implemented both multi-processing and multi-threading. To try one or the other just uncomment the import lines at the top of the code. If you have a progress bar on a single line then you can use the technique that you have of printing '\r' to move the cursor back to the start of the line. But if you want to have multi-line progress bars then you are going to have to get a little fancier. I just cleared the screen each time I wanted to print the progress bars. Check out the article console output on Unix in Python it helped me a great deal in producing the code below. He shows both techniques. You can also give the curses library that is part of python standard library a shot. The question Multiline progress bars asks a similar thing. The main thread/process spawns the child threads that do the work and communicate their progress back to the main thread using a queue. I highly recommend using queues for inter-process/thread communication. The main thread then displays the progress and waits for all children to end execution before exiting itself.

code

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

demo

这篇关于在Python中动态刷新多处理或多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆