2009-02-09 13 views
25

Sto scrivendo un'applicazione di elaborazione della coda che utilizza thread per attendere e rispondere ai messaggi in coda da consegnare all'app. Per la parte principale dell'applicazione, ha solo bisogno di rimanere attivo. Per un esempio di codice come:Python: Passa o Sospendi per processi a esecuzione prolungata?

 
while True: 
    pass 

o

 
while True: 
    time.sleep(1) 

Quale avrà il minimo impatto su un sistema? Qual è il modo migliore per non fare nulla, ma mantenere in esecuzione un'applicazione Python?

+6

La risposta corretta non è quella di fare il polling di I/O affatto. Vedi ad esempio la chiamata select(), dove il sistema operativo è in attesa fino a quando c'è qualcosa di pronto da leggere. –

+0

Bene nel caso dei thread, stanno usando il blocco delle connessioni TCP in attesa sui messaggi. È solo il thread principale di cui sono preoccupato, e non fa nulla se non gestire le opzioni della riga di comando, leggere config e kick dei thread. –

risposta

46

Immagino che time.sleep() abbia un sovraccarico minore sul sistema. Utilizzando il passaggio il farà sì che il ciclo rivaluti immediatamente e pegaggi la CPU, mentre l'utilizzo di time.sleep consentirà di sospendere temporaneamente l'esecuzione.

EDIT: solo per dimostrare il punto, se si avvia l'interprete Python ed eseguire questo:

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

È possibile guardare Python iniziare a mangiare fino 90-100% della CPU istantaneamente, contro:

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

Che registra a malapena sul Monitor attività (utilizzando OS X qui, ma dovrebbe essere lo stesso per ogni piattaforma).

+0

Grazie, ho capito che era il caso, ma continuavo a vedere passare nella documentazione. –

4

Ho sempre visto/sentito che usare il sonno è il modo migliore per farlo. L'uso di sleep manterrà l'utilizzo della CPU dell'interprete Python da selvaggio.

+0

Sì, ha senso! –

6

Non si dà molto contesto a ciò che si sta realmente facendo, ma forse è possibile utilizzare Queue invece di un ciclo di attesa-attesa esplicito? In caso contrario, suppongo che sia preferibile lo sleep, poiché credo che consumerà meno CPU (come altri hanno già notato).

[Modificato in base alle informazioni aggiuntive nel commento qui sotto.]

Forse questo è ovvio, ma in ogni caso, quello che si potrebbe fare in un caso in cui si sta leggendo le informazioni dal socket bloccanti è di aver letto un thread dal socket e inviare messaggi opportunamente formattati in uno Queue, e poi avere il resto dei thread "di lavoro" che leggono da quella coda; i lavoratori blocceranno quindi la lettura dalla coda senza che sia necessario né lo pass né lo sleep.

+0

Grazie per il suggerimento in coda sembra a portata di mano, in questa applicazione sto usando i socket di blocco per ascoltare i messaggi da un broker AMQP (in thread separati) e agire su di essi al momento del ricevimento. –

+0

@Crad: quindi utilizzare select per attendere su un socket, in modo simile a come funziona una coda. Non utilizzare l'attesa o il polling. –

22

Perché dormire? Non vuoi dormire, vuoi aspettare che i fili finiscano.

Così

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

See: thread.join

+1

Non mi aspetto che i thread finiscano, comunque. Questo è un processo senza fine. Questa logica si applica ancora? –

+0

Ovviamente la logica si applica ancora. Eviteresti di sprecare anche i pochi cicli per un sonno "in loop". – tzot

+0

Questo non sembra funzionare, poiché i thread non dovrebbero terminare il processo è terminato, il timeout potrebbe concettualmente venire sempre per primo, o mi manca qualcosa? –

0

Esecuzione di un metodo come un thread in background con il sonno in 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

Se siete alla ricerca di una breve, zero cpu modo per loop per sempre fino a un KeyboardInterrupt, è possibile utilizzare:

from threading import Event 

Event().wait() 

Per alcuni sfondo, Event oggetti sono normalmente utilizzati per l'attesa per i processi in esecuzione lunghi per completare:

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

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

print('Continuing...') 

che stampa:

Task complete. 
Continuing... 
Problemi correlati