2010-03-20 19 views
8

Nel mio script, ho una funzione pippo che fondamentalmente utilizza pynotify per informare l'utente su qualcosa ripetutamente dopo un intervallo di tempo di 15 minuti.Devo usare la forcella o i fili?

def foo: 
    while True: 
     """Does something""" 
     time.sleep(900) 

mio script principale deve interagire con l'utente & fa tutte le altre cose così ho appena cant chiamano la funzione foo(). direttamente.

Qual è il modo migliore di farlo e perché? Utilizzo della forcella o dei fili?

+0

Hmm due risposte contraddittorie ... – kennytm

+0

@Kenny TM: Non sorprende. "Meglio" non è definito nella domanda. Inoltre, è altamente discutibile per la maggior parte delle definizioni di "Migliore". –

risposta

9

io non vi dirò quale usare, ma qui ci sono alcuni dei vantaggi di ciascuna:

discussioni può iniziare in modo più rapido rispetto ai processi e thread utilizzare meno risorse del sistema operativo di processi, tra cui memoria, handle di file, ecc. I thread ti danno anche la possibilità di comunicare attraverso variabili condivise (anche se molti direbbero che è più uno svantaggio che un vantaggio - vedi sotto).

I processi hanno ciascuno la propria memoria e variabili separate, il che significa che i processi generalmente comunicano inviando messaggi l'uno all'altro. Questo è molto più facile da fare correttamente di thread che comunicano tramite memoria condivisa. I processi possono anche essere eseguiti in modo concorrente, in modo che se si dispone di più core CPU, è possibile mantenerli tutti occupati utilizzando i processi. In Python *, lo global interpreter lock impedisce ai thread di utilizzare molto più di un singolo core.


* - Cioè, CPython, che l'attuazione di Python che si ottiene se si va a http://python.org e scaricare Python. Altre implementazioni Python (come Jython) non impediscono necessariamente a Python di eseguire thread su più CPU contemporaneamente. Grazie a @EOL per il chiarimento.

+0

Ho usato i thread bcos l'attività non è stata intensiva della CPU e inoltre non ho usato per fork poichè è anche più lenta per creare un PCB completamente nuovo .. –

+3

Probabilmente vuoi dire "In CPython, il blocco dell'interprete globale ...". In effetti, non c'è GIL in alcune altre implementazioni Python (Jython, Iron Python, ...). – EOL

+0

@EOL - Abbastanza vero. Supponevo che l'interrogante stia usando CPython, dato che la gente di solito specifica se sta usando qualcosa * altro * rispetto a CPython. Punto preso, però - aggiornerò la mia risposta. –

3

I processi sono molto più semplici. Basta girarli e lasciare che sia il sistema operativo a gestirli.

Inoltre, i processi sono spesso molto più efficienti. I processi non condividono un pool comune di risorse I/E; sono completamente indipendenti.

Python's subprocess.Popen gestisce tutto.

+0

+1 da parte mia - S. Lott è molto più autorevole di me, specialmente quando si tratta di Python. – duffymo

1

Se per fork si intende os.fork, eviterei di utilizzarlo. Non è multipiattaforma e livello troppo basso: è necessario implementare la comunicazione tra i processi.

Se si desidera utilizzare un processo separato, utilizzare il modulo subprocess oppure se si utilizza Python 2.6 o versioni successive il nuovo modulo multiprocessing. Questo ha un'API molto simile al modulo di threading, quindi è possibile iniziare a utilizzare i thread e quindi passare facilmente ai processi o viceversa.

Per quello che vuoi fare, penso che userei i thread, a meno che lo """does something""" richieda un uso intensivo della CPU e tu voglia approfittare di più core, che dubito in questo caso particolare.

+0

Se ho un uso intensivo della CPU, quale scegliere? E perché? –

4

Per questi tipi di problemi, né i thread né i processi biforcati sembrano l'approccio corretto. Se tutto ciò che si vuole fare è una volta ogni 15 minuti informare l'utente di qualcosa, perché non utilizzare un ciclo di eventi come il reattore di GLIB o di Twisted? Ciò consente di pianificare le operazioni che dovrebbero essere eseguite una volta ogni tanto, e andare avanti con il resto del programma.

+0

Sono un principiante quindi non ho idea di come implementarlo. Ma la tua risposta sembra convincente ... –

4

L'utilizzo di più processi consente di sfruttare più core della CPU contemporaneamente, mentre, in CPython, l'utilizzo dei thread non avviene (i thread si alternano utilizzando un singolo core della CPU), quindi, se si utilizza un lavoro intensivo della CPU e assolutamente vuoi usare i thread, dovresti considerare Jython o IronPython; con CPython, questa considerazione è spesso sufficiente per influenzare la scelta verso il modulo multiprocessing e lontano da quello threading (offrono interfacce abbastanza simili, perché multiprocessing è stato progettato per essere facilmente messo in luogo al posto di threading).

Al netto di questa considerazione cruciale, i thread potrebbero spesso essere una scelta migliore (in termini di prestazioni) su Windows (dove creare un nuovo processo è un'attività pesante), ma meno spesso sulle varianti di Unix (Linux, versioni BSD, OpenSolaris, MacOSX, ...), dal momento che creare un nuovo processo è più veloce lì (ma se usi IronPython o Jython, dovresti controllare, sulle piattaforme che ti interessano, che questo si applica ancora alle macchine virtuali in questione - CLR con .NET o Mono per IronPython, la tua JVM di scelta per Jython).