在Python中动态刷新多处理或多线程 [英] Dynamic refresh printing of multiprocessing or multithreading in 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屋!