2009-12-15 8 views
8

Voglio dire ai miei thread Python di produrre, e quindi evitare inutilmente la CPU. In Java, è possibile farlo utilizzando la funzione Thread.yield(). Non penso che ci sia qualcosa di simile in Python, quindi ho usato time.sleep(t) dove t = 0.00001. Per t=0 sembra non esserci alcun effetto.C'è qualcosa di simile a Thread.yield() di Java in Python? Ha senso?

Penso che forse c'è qualcosa che non sto capendo correttamente sul modello di threading di Python, e quindi il motivo per il thread.yield() mancante. Qualcuno può chiarirmi questo? Grazie!

PS: Questo è ciò che la documentazione per Java di Thread.yield() dice:

causa il thread oggetto attualmente in esecuzione per mettere in pausa e consentire altri thread per eseguire temporaneamente.

+1

quando t = 0, restituisce per qualsiasi altro thread che è pronto –

+0

Ok. Grazie. Ci ho provato ma non sembra funzionare. Forse sto misurando in modo errato. – Carlos

risposta

3

L'interprete passa da un thread ad un altro periodicamente in ogni caso senza il vostro intervento - non c'è bisogno di dire che il sistema non a 'hog' un filo.

Tuttavia, in circostanze normali, solo un thread Python è in esecuzione in qualsiasi momento. (Le eccezioni tendono a ruotare attorno ai tempi in cui i thread sono in attesa di input da dispositivi esterni come il disco rigido o la rete.) Ciò è dovuto allo Global Interpreter Lock. Ciò significa tuttavia che probabilmente non stai ottenendo il massimo beneficio dai thread in Python come faresti in Java o in molti altri linguaggi. Spostarsi su questo problema non è necessariamente banale, anche se passare a multiprocessing invece di multithreading è un buon approccio, se possibile.

Tuttavia, ciò che si vuole fare sembra in qualche modo imperfetto - se si dispone di 2 thread e entrambi hanno del lavoro da fare, non è necessario scrivere codice sul lato dell'applicazione per passare da uno all'altro. Questo è il lavoro del sistema operativo o della macchina virtuale. Se ti accorgi di dire a un thread di "fare meno" perché vuoi favorire un altro thread in termini di tempo del processore, invece di aggiungere un rendimento o un sonno arbitrario, dovresti probabilmente impostare le priorità del thread. (Anche se di nuovo, questo potrebbe non avere molto significato in Python data la presenza del Global Interpreter Lock.)

+0

Cosa succede quando un thread non sta cedendo, è che inizia a morire di fame gli altri thread. Java e C (pthreads) hanno funzioni redditizie per dire allo schedulatore che il thread è "libero". La risposta qui: http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python/787810#787810 sembra dare qualche ulteriore intuizione, ma sembra che non riesca ad aggirarlo. – Carlos

+0

Penso che tu abbia frainteso il modo in cui i thread funzionano sulla maggior parte dei sistemi. Il sistema passerà automaticamente da un thread all'altro in modo molto regolare, consentendo l'esecuzione di tutti i thread. (Questo è chiamato "pre-emption" o "pre-processo multitasking".) Non è necessario passare manualmente da uno all'altro su Java o Python. Metodi come yield() su tali sistemi sono un'ottimizzazione minore, non un requisito. – Kylotan

+1

No, no. Conosco la prelazione. Il "rendimento" a cui mi riferisco (nel caso di Java o pthreads) sta semplicemente consigliando lo schedulatore. È un modo per suggerire un punto di prelazione. Come dici tu è un'ottimizzazione. Devo andare a leggere di più sul GIL. Grazie. – Carlos

0

Thread.yield() manca a Python perché forse è stato dimenticato, oppure il progettista ha pensato che tutte le sincronizzazioni e i problemi di comunicazione tra processi sono risolvibili senza Thread.yield().

userei Thread.yield() per il seguente problema:

Ad es c'è una coda di lavoro e ci sono 2 thread di lavoro che possono recuperare le voci dalla coda dei lavori e inserire le voci nella coda dei lavori. Un modo per risolverlo è usare la filettatura. Classe di condizioni. Quando il lavoratore 'B' vuole recuperare una voce di coda, ma la coda è vuota, passa allo stato di attesa (Condition.wait()). Quando il lavoratore "A" inserisce la voce nella coda, si attiva il lavoratore "B" (Condition.notify()). A questo punto la resa è essenziale, perché se il lavoratore 'A' non cede qui, il lavoratore 'A' può recuperare il compito prima del lavoratore svegliato 'B' che causa un problema di razza.

Mi chiedo come sia risolvibile senza Thread.yield().

+3

L'OP non ha chiesto perché 'thread.yield()' non è presente in python? Non penso che una spiegazione di 'thread.yield()' sia adatta alla domanda. – m02ph3u5

+0

Sicuro. Ma molte persone stanno discutendo sul fatto che la resa non è necessaria, a causa della prelazione. Penso che thread.yield() sia mancante, perché è stato semplicemente dimenticato. – Endre

+0

Ok, ho modificato la mia risposta per dare una possibile risposta al "perché manca?" domanda. – Endre

Problemi correlati