2009-02-09 15 views
25

Estoy escribiendo una aplicación de procesamiento de colas que utiliza subprocesos para esperar y responder a los mensajes de cola que se entregarán a la aplicación. Para la parte principal de la aplicación, solo necesita mantenerse activo. Por ejemplo, un código como:Python: ¿pasar o suspender para procesos de larga ejecución?

 
while True: 
    pass 

o

 
while True: 
    time.sleep(1) 

Cuál va a tener el menor impacto en un sistema? ¿Cuál es la forma preferida de no hacer nada, pero mantener una aplicación de Python ejecutándose?

+6

La respuesta correcta no es hacer el sondeo de E/S en absoluto. Ver por ejemplo la llamada select(), donde el sistema operativo duerme hasta que haya algo listo para leer. –

+0

Bueno, en el caso de los subprocesos, están usando conexiones TCP de bloqueo en espera de mensajes. Es solo el hilo principal que me preocupa, y no hace otra cosa que manejar las opciones de línea de comando, configuración de lectura y puntapié de hilos. –

Respuesta

46

Imagino que time.sleep() tendrá menos sobrecarga en el sistema. El uso de pase hará que el ciclo vuelva a evaluar inmediatamente y sincronice la CPU, mientras que el uso de time.sleep permitirá suspender temporalmente la ejecución.

EDITAR: sólo para probar el punto, si inicia el intérprete de Python y ejecuta este:

>>> while True: 
...  pass 
... 

Es posible ver Python empezar a comer hasta el 90-100% de la CPU al instante, frente:

>>> import time 
>>> while True: 
...  time.sleep(1) 
... 

que apenas se registra en el Monitor de actividad (usando OS X aquí pero debería ser el mismo para cada plataforma).

+0

Gracias, pensé que ese era el caso, pero seguí viendo pasar la documentación. –

4

Siempre he visto/escuchado que usar el sueño es la mejor manera de hacerlo. Usar sleep evitará que el uso de la CPU de tu intérprete de Python se vuelva loco.

+0

¡Sí, tiene sentido! –

6

No le da mucho contexto a lo que realmente está haciendo, pero ¿podría usarse Queue en lugar de un explícito bucle ocupado-espera? De lo contrario, supondría que sería preferible sleep, ya que creo que consumirá menos CPU (como otros ya han notado).

[Editado acuerdo con información adicional en el comentario a continuación.]

Tal vez esto es obvio, pero de todos modos, lo que podría hacer en un caso en el que está leyendo la información de los zócalos de bloqueo es tener lectura de un hilo desde el socket y publique los mensajes adecuadamente formateados en un Queue, y luego tenga el resto de sus hilos "worker" leyendo de esa cola; los trabajadores bloquearán la lectura de la cola sin necesidad de pass ni sleep.

+0

Gracias por la sugerencia de Queue parece útil, en esta aplicación estoy usando sockets de bloqueo para escuchar los mensajes de un intermediario de AMQP (en hilos separados) y actuar sobre ellos al recibirlos. –

+0

@Crad: a continuación, use seleccionar para esperar en un socket, similar a la forma en que funciona la cola. No use la espera o el sondeo ocupados. –

22

¿Por qué dormir? No quieres dormir, quieres esperar a que terminen los hilos.

Así

# store the threads you start in a your_threads list, then 
for a_thread in your_threads: 
    a_thread.join() 

Ver: thread.join

+1

No espero que los hilos terminen. Este es un proceso sin fin. ¿Sigue siendo válida esta lógica? –

+0

Por supuesto, la lógica todavía se aplica. Evitaría desperdiciar incluso los pocos ciclos para un sueño "en bucle". – tzot

+0

Esto no parece funcionar, dado que los hilos no deberían finalizar, el proceso finaliza, el tiempo de espera podría conceptualmente siempre ser el primero, o ¿me falta algo? –

0

Ejecución de un método como un subproceso de fondo con el sueño en Python

import threading 
    import time 


    class ThreadingExample(object): 
     """ Threading example class 
     The run() method will be started and it will run in the background 
     until the application exits. 
     """ 

     def __init__(self, interval=1): 
      """ Constructor 
      :type interval: int 
      :param interval: Check interval, in seconds 
      """ 
      self.interval = interval 

      thread = threading.Thread(target=self.run, args=()) 
      thread.daemon = True       # Daemonize thread 
      thread.start()         # Start the execution 

     def run(self): 
      """ Method that runs forever """ 
      while True: 
       # Do something 
       print('Doing something imporant in the background') 

       time.sleep(self.interval) 

    example = ThreadingExample() 
    time.sleep(3) 
    print('Checkpoint') 
    time.sleep(2) 
    print('Bye') 
2

Si usted está buscando un corto, cero-cpu forma de bucle para siempre hasta un KeyboardInterrupt, puede utilizar:

from threading import Event 

Event().wait() 

Para algunos antecedentes, Event objetos se utilizan normalmente para la espera de los procesos de ejecución larga para completar:

def do_task(): 
    sleep(10) 
    print('Task complete.') 
    event.set() 

event = Event() 
Thread(do_task).start() 
event.wait() 

print('Continuing...') 

que imprime:

Task complete. 
Continuing... 
Cuestiones relacionadas