Impresión dinámica de actualización de multiprocesamiento o multiproceso en Python

He implementado un descargador multiprocesamiento. ¿Cómo puedo imprimir la barra de estado (tasa completa, velocidad de descarga) que se puede actualizar automáticamente en diferentes partes del terminal?

Me gusta esto:

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

código:

 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 hereda la clase de proceso y activa el método de descarga.

Yo uso la cola para almacenar la url. Aquí está el proceso de inicio

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

A continuación se muestra una demostración que ha implementado tanto el multiprocesamiento como el multiproceso. Para probar uno u otro simplemente descomente las líneas de importación en la parte superior del código. Si tiene una barra de progreso en una sola línea, puede utilizar la técnica que tiene para imprimir ‘\ r’ para mover el cursor de nuevo al inicio de la línea. Pero si quieres tener barras de progreso multilínea, entonces tendrás que ser un poco más sofisticado. Acabo de borrar la pantalla cada vez que quería imprimir las barras de progreso. Echa un vistazo a la salida de la consola del artículo en Unix en Python . Él muestra ambas técnicas. También puede darle un tiro a la biblioteca de curses que forma parte de la biblioteca estándar de python. La pregunta Barras de progreso multilínea plantea algo similar. El subproceso / proceso principal genera los subprocesos secundarios que realizan el trabajo y comunican su progreso de nuevo al subproceso principal mediante una cola. Recomiendo usar colas para la comunicación entre procesos y subprocesos. El hilo principal luego muestra el progreso y espera a que todos los hijos finalicen la ejecución antes de salir.

código

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

manifestación

introduzca la descripción de la imagen aquí