Señalización entre hilos en Python

Estoy trabajando en un capturador de datos en tiempo real. Tengo un ciclo while True, y dentro de él genero subprocesos que realizan tareas relativamente pequeñas (estoy consultando una API de terceros a través de HTTP, y para lograr velocidades rápidas estoy consultando en paralelo).

Cada hilo se encarga de actualizar una serie de datos específica. Esto puede tardar 2, 3 o incluso 5 segundos. Sin embargo, mi bucle while True podría generar subprocesos más rápido que el tiempo que tarda en finalizar el subproceso. Por lo tanto, necesito que los subprocesos generados esperen a que finalicen los subprocesos anteriores.

En general, es impredecible cuánto tardan los subprocesos en finalizar porque los subprocesos consultan un servidor HTTP...

Estaba pensando en crear un semáforo con nombre para cada subproceso, y luego, si un subproceso generado para una serie específica encuentra un subproceso anterior que funciona en la misma serie, esperará.

El único problema que puedo ver es una posible acumulación de hilos.

¿Cuál es la mejor solución aquí? ¿Debería investigar cosas como el apio? Actualmente estoy usando el módulo de subprocesamiento.

¡Gracias!

preguntado el 15 de mayo de 12 a las 16:05

Si la tarea está vinculada a la CPU, el uso de subprocesos no le brindará beneficios de rendimiento debido a GIL. -

Si tiene datos paralelos pero no tiene cola, lo está haciendo mal. Debe tener algunos trabajadores que toman su entrada (es decir, una URL para descargar) de una cola y colocan su resultado (los datos descargados) en otra cola. Otros trabajadores pueden usar esta cola para seguir procesando los datos y así sucesivamente. -

3 Respuestas

¡NO! Por favor, por el amor de tu Dios o diseñador inteligente, ¡no hagas eso! No cree/engendre/cualesquiera que sean los subprocesos continuamente y trate de microgestionarlos. Threadpool: cree algunos subprocesos al inicio y páseles una cola de productor-consumidor para esperar instancias de clase que representen esas tareas HTTP.

contestado el 15 de mayo de 12 a las 16:05

Deberías usar Queue.Queue. Cree una cola para cada serie y un hilo para escuchar en esa cola. Cada vez que necesites leer una serie, pon una solicitud en la cola. El subproceso espera elementos en la cola, y cada uno que recibe, lee los datos.

contestado el 15 de mayo de 12 a las 16:05

Otra opción que podría usar si solo está volviendo a consultar la API cada vez que regresa una de sus consultas es un marco asíncrono como Twisted (Su tutorial sobre Threading). Soy un principiante relativo de Twisted, por lo que puede haber mejores formas de torcer Twisted para tu tarea que esta:

from twisted.internet import reactor, defer
def simple_task():
    status = query_your_api()
    return status

def repeating_call(status):
    print(status)
    d = threads.deferToThread(simple_task)
    d.addCallback(repeating_call)

data_series = [data1, data2, data3]
for data in data_series:
    repeating_call('starting everything up')

reactor.run()

contestado el 15 de mayo de 12 a las 17:05

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