2011-11-23 11 views
15

estoy usando Python 2.7, que tienen un código que se parece a esto:tareas que se ejecutan en paralelo en pitón

task1() 
task2() 
task3() 
dependent1() 

task4() 
task5() 
task6() 
dependent2() 

dependent3() 

Las únicas dependencias aquí son las siguientes: dependent1 tiene que esperar a que tasks1-3, dependent2 necesidades esperar las tareas 4-6 y dependiente3 necesita esperar dependientes1-2 ... Lo siguiente estaría bien: ejecutar las 6 tareas en primer lugar en paralelo, luego las dos primeras dependientes en paralelo ... luego la dependiente final

Prefiero tener la mayor cantidad de tareas posible ejecutando en paralelo, he buscado en Google algunos módulos, pero esperaba evitar las bibliotecas externas, y no estoy seguro de cómo el Que La técnica ue-Thread puede resolver mi problema (¿alguien puede recomendar un buen recurso?)

+0

Recomiendo usar los métodos * Queue.task_done * y * Queue.join * de la biblioteca estándar para sincronizar los hilos. En la parte inferior de la página en los documentos de Queue, encontrará un ejemplo de cómo esperar a que otros subprocesos finalicen sus tareas: http://docs.python.org/library/queue.html#Queue.Queue.join –

+0

Si su código se vuelve más complejo, vale la pena examinar las bibliotecas externas, porque ya hay cosas que hacer frente a la ejecución de tareas en paralelo al mismo tiempo que se asegura de que las dependencias se ejecuten en orden. –

+0

Debido a GIL, los hilos solo se ejecutarán uno a la vez en python estándar. Sin embargo, las versiones futuras de Pypy usando STM pueden evitar esto. –

Respuesta

24

La clase integrada threading.Thread ofrece todo lo que necesita: start para iniciar un nuevo hilo y join para esperar al final de un hilo.

import threading 

def task1(): 
    pass 
def task2(): 
    pass 
def task3(): 
    pass 
def task4(): 
    pass 
def task5(): 
    pass 
def task6(): 
    pass 

def dep1(): 
    t1 = threading.Thread(target=task1) 
    t2 = threading.Thread(target=task2) 
    t3 = threading.Thread(target=task3) 

    t1.start() 
    t2.start() 
    t3.start() 

    t1.join() 
    t2.join() 
    t3.join() 

def dep2(): 
    t4 = threading.Thread(target=task4) 
    t5 = threading.Thread(target=task5) 

    t4.start() 
    t5.start() 

    t4.join() 
    t5.join() 

def dep3(): 
    d1 = threading.Thread(target=dep1) 
    d2 = threading.Thread(target=dep2) 

    d1.start() 
    d2.start() 

    d1.join() 
    d2.join() 

d3 = threading.Thread(target=dep3) 
d3.start() 
d3.join() 

Como alternativa a unirse puede utilizar Queue.join a esperar hasta el final hilos.

+1

¡Esto es genial! pero mis funciones devuelven los valores que uso en las funciones dep, ¿cómo obtengo los valores devueltos de t1, t2, t3, etc.? –

+2

Primer golpe en SO me da http://stackoverflow.com/questions/1886090/return-value-from-thread – gecco

+0

¿Qué pasa si quiero pasar algunos argumentos a la función? – Lavish

2

Mire Gevent.

Ejemplo de Uso:

import gevent 
from gevent import socket 

def destination(jobs): 
    gevent.joinall(jobs, timeout=2) 
    print [job.value for job in jobs] 

def task1(): 
    return gevent.spawn(socket.gethostbyname, 'www.google.com') 

def task2(): 
    return gevent.spawn(socket.gethostbyname, 'www.example.com') 

def task3(): 
    return gevent.spawn(socket.gethostbyname, 'www.python.org') 

jobs = [] 
jobs.append(task1()) 
jobs.append(task2()) 
jobs.append(task3()) 
destination(jobs) 

esperanza, esto es lo que ha estado buscando.

+2

¿De verdad? El OP solicitó una solución de subprocesamiento múltiple utilizando una técnica Queue/Thread y quería evitar las bibliotecas externas. Pero lo señala a un nido de dependencias externas e ignora las soluciones básicas proporcionadas por la biblioteca estándar. –

+2

Punto bien tomado. – meson10

Cuestiones relacionadas