2010-02-01 16 views
6

esta pregunta se refiere a las penalidades de rendimiento que pueden surgir o no de tener una gran cantidad de subprocesos python dormidos en un servidor web.Python: penalización por hilos inactivos

Antecedentes: estoy implementando una tienda en línea usando django/satchmo. Un requisito es para el pago retrasado. El cliente puede reservar un producto y permitir que un tercero lo pague en una fecha posterior (a través de una URL aleatoria y única).

Para manejar la falta de mantenimiento de un artículo, estoy creando un hilo que dormirá durante el tiempo de reserva y luego elimino la reserva/marca el producto como vendido cuando despierta. Se ve así:

#Reserves a product when it is placed in the cart 
def reserve_cart_product(product): 
    log.debug("Reserving %s" % product.name) 
    product.active = False 
    product.featured = False 
    product.save() 
    from threading import Timer 
    Timer(CART_RESERVE_TIME, check_reservation, (product,)).start() 

estoy usando la misma técnica cuando el sacrificio de los URLs únicas después de que hayan expirado, sólo el temporizador duerme durante mucho más tiempo (típicamente 5 días).

Por lo tanto, mi pregunta para que también lo es de la siguiente manera:

está teniendo un gran numnber de hilos va a afectar seriamente el rendimiento de dormir? ¿Hay mejores técnicas para programar un evento único en algún momento en el futuro? Me gustaría mantener esto en python si es posible; sin llamadas at o cron a través de sys.

El sitio no es exactamente de alto tráfico; un límite superior (generoso) para los productos pedidos por semana sería de alrededor de 100. Combinado con la reserva de la compra, esto podría significar que hay más de 100 hilos para dormir en cualquier momento. ¿Lamentaré las tareas de programación de esta manera?

Gracias

+1

Es posible que desee una solución más persistente que los hilos en caso de que su servidor se caiga. Por lo que puedo decir, tendrá que buscar en su archivo de registro para saber qué productos se reservaron después de un bloqueo (aunque no sabrá cuánto tiempo estuvieron reservados para el código anterior). – tgray

+0

Haces un buen punto y es por esta razón que he comenzado a almacenar algunos registros en la base de datos. – pisswillis

+0

Supongo que su servidor no se reiniciará y no obtendrá miles de pedidos, ¿verdad? Una opción más robusta sería un sistema persistente de cola de bases de datos, como RabbitMQ. –

Respuesta

7

No veo ninguna razón por la que esto no debería funcionar. El código subyacente para Timer (en threading.py) simplemente usa time.sleep. Una vez que ha estado esperando por un tiempo, básicamente ejecuta un ciclo con time.sleep (0.05) Esto debería resultar en un uso de CPU de básicamente 0%, incluso con cientos de subprocesos. Aquí está un ejemplo sencillo, donde me di cuenta de 0% de uso de CPU para el proceso de pitón:

import threading 

def nothing(): 
    pass 

def testThreads(): 
    timers = [threading.Timer(10.0, nothing) for _ in xrange(881)] 
    print "Starting threads." 
    map(threading.Thread.start, timers) 
    print "Joining threads." 
    map(threading.Thread.join, timers) 
    print "Done." 

if __name__ == "__main__": 
    testThreads() 

El problema real es que puede que no sea capaz de iniciar realmente demasiadas hebras. En mi sistema de 64 GB de 64 bits, solo puedo iniciar 881 hilos antes de recibir un error. Si realmente solo tienes unos pocos cientos, no puedo imaginar que no funcionará.

3

Por lo general, los subprocesos no tienen sobrecarga aparte de la memoria asignada para sus pilas y otros datos privados. Los algoritmos de programación del sistema operativo moderno tienen complejidad O (1) por lo que incluso un hilo en ejecución no introduce una sobrecarga, que no sea la huella de memoria. Al mismo tiempo, es difícil imaginar un diseño eficiente que requiera muchos hilos. El único caso que puedo imaginar es la comunicación con muchos otros compañeros. En este caso, debe usarse IO asíncrono.

4

100 hilos no es un problema, pero como tgray pointed out, ¿qué sucede si el servidor se cae (corte de energía, mantenimiento planificado, falla de hardware, etc.)?

Necesita almacenar la información de desuscripción en su base de datos en algún lugar.

Luego, puede hacer que un trabajo cron active periódicamente un script de reserva, por ejemplo, y no necesita tener todos esos hilos alrededor.

Si realmente no desea utilizar cron, solo tiene un hilo de trabajo que duerme por un minuto y luego verifica si se debe alguna de las desconexiones.

Cuestiones relacionadas