python - usando múltiples procesos / procesamiento paralelo

Así que escribí una pequeña secuencia de comandos de Python que me permite especificar una carpeta que contiene archivos de video y algún directorio de salida, y el programa recorre todos los archivos de video y los convierte usando el freno de mano como:

proc = subprocess.Popen('HandBrakeCLI -i ... -o ...')
proc.wait()

Así lo hace cada archivo en el directorio, uno por uno. Tengo una máquina de cuatro núcleos y quiero acelerar las cosas haciendo conversiones de video en paralelo, pero no entiendo completamente cómo abordar eso.

¿Necesito algo como os.fork()? ¿Algo más como el módulo de multiprocesamiento? Vengo de la tierra de javascript de un solo subproceso, por lo que esto es relativamente nuevo para mí.

Gracias por cualquier ayuda!

preguntado el 22 de mayo de 12 a las 18:05

2 Respuestas

Algo similar a esto debería hacer el truco:

import multiprocessing
...
def wrapper(currentfile):
    #create your commandline -- for the sake of simplicity, I assume that
    #the only thing that changes is the filename you are passing to
    #HandBrakeCLI (and that the filename is the last argument to pass)
    cmd='HandBrakeCLI -i ... -o ... '+currentfile 
    proc = subprocess.Popen(cmd)
    proc.wait()
    return 'foo'

files=os.listdir(path)  #Any way that you build up your list of files is fine
output = multiprocessing.Pool(4).map(wrapper,files) #output is ['foo', 'foo', ..., 'foo']

Por supuesto, esto utiliza un map-como función para sus efectos secundarios que a muchas personas de python no les gustan ... pero me parece lo suficientemente intuitivo, especialmente si dejas un comentario. También hice que la función devolviera 'foo' para demostrar que puede acceder al valor devuelto desde la función con bastante facilidad.

contestado el 22 de mayo de 12 a las 18:05

Sugeriría usar el enviado Biblioteca. Debajo del capó, utiliza la biblioteca de subprocesos para generar nuevos programas de línea cmd, por lo que si usa el connect funcionar así:

import envoy
proc = envoy.connect('HandBrakeCLI -i ... -o ...')
while proc.status_code = None:
    sleep(5)

Puedes generar tantos como quieras a la vez y esperar hasta que uno salga antes de generar otro. Tenga en cuenta que si tiene problemas, tengo un tenedor con mis correcciones que es posible que desee comprobar.

Me encontré con un problema de cotización en la forma en que la biblioteca shlex maneja las cotizaciones y lo que espera su programa de línea cmd. Y, dado que lo usé en Windows, en un problema de modo posix/no posix.

contestado el 22 de mayo de 12 a las 18:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.