24

Sto realizzando un programma per eseguire simulazioni in Python, con un'interfaccia wxPython. Nel programma, è possibile creare una simulazione e il programma esegue il rendering (= calcola) per te. Il rendering può richiedere molto tempo.Multiprocessing o multithreading?

Quando l'utente avvia una simulazione e definisce uno stato iniziale, voglio che il programma renda la simulazione continuamente in background, mentre l'utente potrebbe fare cose diverse nel programma. Un po 'come una barra in stile YouTube che si riempie: puoi giocare la simulazione solo fino al punto che è stato renderizzato.

Devo utilizzare più processi o più thread o cosa? La gente mi ha detto di usare il pacchetto multiprocessing, l'ho controllato e sembra buono, ma ho anche sentito che i processi, a differenza dei thread, non possono condividere molte informazioni (e penso che il mio programma dovrà condividere molte informazioni .) Inoltre ho anche sentito parlare di Stackless Python: è un'opzione separata? Non ne ho idea.

Si prega di avvisare.

+0

Sono preoccupato per il tuo "Penso che il mio programma dovrà condividere molte informazioni" - vuoi dire che non lo sai ancora ?? Forse dovresti fare più lavoro di progettazione. Il modulo di multiprocessing è liberamente compatibile con il modulo di threading, quindi il passaggio non dovrebbe essere un grande sforzo. Ma attenzione al GIL che mi farebbe preferire il multiprocessing. – CyberFonic

risposta

1

Preferisco sempre più thread per semplicità, ma c'è un problema reale con affinità. Non c'è modo (che io sappia) di dire all'implementazione di threading di Python di collegarsi a un processore specifico. Questo potrebbe non essere un problema per te, non sembra come dovrebbe essere. A meno che tu non abbia una buona ragione per non farlo, sembra che il tuo problema possa essere risolto facilmente con l'implementazione del threading di Python.

Se si decide di utilizzare l'elaborazione, la condivisione delle informazioni tra i processi secondari può essere eseguita in diversi modi: connessioni tcp/udp, memoria condivisa o pipe. Aggiunge un po 'di sovraccarico e complessità.

+1

+1: Il threading è un formato molto, molto naturale per lavorare con GUI basate su eventi, e aiuta a evitare il dolore delle comunicazioni tra processi (a meno che le vostre esigenze di condivisione delle informazioni siano adatte alle opzioni limitate di cui parlava Shane). – ojrac

+1

1. I thread avvantaggiano automaticamente tutti i core della CPU? 2. Hai un'idea di come Stackless si inserisce in tutto questo? –

+0

Il problema dei thread è che sono "generalmente" sotto il controllo del sistema operativo e tutti i sistemi operativi sono un buon lavoro di distribuzione dei carichi attraverso le CPU. Questo è generalmente il comportamento che vuoi. Puoi immaginare scenari in cui ti piacerebbe bing una singola attività per una singola CPU. –

18

"ho controllato fuori e si guarda bene, ma ho anche sentito che i processi, a differenza di thread, non possono condividere un sacco di informazioni ..."

Questo è vero solo in parte.

I thread fanno parte di un processo - thread condivide la memoria banalmente. Il che è tanto un problema quanto un aiuto: due thread con indifferenza casuale l'uno per l'altro possono sovrascrivere la memoria e creare seri problemi.

I processi, tuttavia, condividono le informazioni attraverso molti meccanismi. Una pipeline Posix (a | b) significa che elabora ed elabora le informazioni sulla condivisione: una la scrive e la legge. Funziona molto bene per molte cose.

Il sistema operativo assegnerà i processi a tutti i core disponibili con la stessa rapidità con cui li crei. Funziona molto bene per un sacco di cose.

Python senza stack non è correlato a questa discussione: è più veloce e ha una programmazione di thread diversa. Ma non penso che i fili siano la via migliore per questo.

"Penso che il mio programma dovrà condividere molte informazioni."

Si consiglia di risolvere prima questo. Quindi, determinare come strutturare i processi attorno al flusso di informazioni. Una "pipeline" è molto semplice e naturale da fare; qualsiasi shell creerà banalmente la pipeline.

Un "server" è un'altra architettura in cui più processi client ottengono e/o inseriscono informazioni in un server centrale. Questo è un ottimo modo per condividere informazioni. È possibile utilizzare l'implementazione di riferimento WSGI come un modo per creare un server semplice e affidabile.

14
  • Stackless: utilizza 1 CPU. "Tasklet" devono arrendersi volontariamente. L'opzione di prelazione non funziona sempre.
  • Filettato: utilizza 1 CPU. I thread nativi condividono il tempo in modo casuale dopo l'esecuzione di 20-100 opcode python.
  • Multiprocessing: utilizza CPU multipla

Aggiornamento

Indepth Analisi

Usa filettato per un momento facile. Tuttavia, se chiamate routine C che richiedono un tempo di lungo prima di tornare, questa potrebbe non essere una scelta se la routine C non rilascia il blocco.

Utilizzare multiprocessing se è molto limitato dalla potenza della cpu ed è necessaria la massima reattività.

Non utilizzare stackless, l'ho avuto prima segfault e i thread sono praticamente equivalenti a meno che non ne utilizziate centinaia o più.

+5

È la prima volta che sento qualcuno dire che il threading è facile. Il codice thread IMO è molto difficile da scrivere bene. –

5

Con CPython più thread non possono essere eseguiti contemporaneamente a causa della GIL: link text.

Penso che sia ancora possibile che i thread aumentino l'applicazione, ad es. un thread potrebbe bloccare l'I/O mentre un altro funziona.

Se non hai mai utilizzato i thread, ti suggerisco di provarli prima. Sarà utile in qualsiasi altra lingua e troverai molte risorse sul web. Quindi se ti rendi conto che hai bisogno di più parallelismi, puoi comunque tornare ai processi.

10

Un processo ha il proprio spazio di memoria. Rende più difficile condividere le informazioni, ma rende anche il programma più sicuro (meno necessità di sincronizzazione esplicita). Detto questo, i processi possono condividere la stessa memoria in modalità di sola lettura.

Un thread è più economico da creare o uccidere, ma la differenza principale è che condivide la memoria con altri thread nello stesso processo. Questo è a volte rischioso e, in aggiunta, il processo di arresto potrebbe uccidere tutti i thread.

Un vantaggio dell'utilizzo di più processi su più thread è che sarebbe più semplice scalare il programma in modo che funzioni con più macchine che comunicano tramite i protocolli di rete.

Ad esempio, è possibile eseguire potenzialmente 16 processi su 8 macchine dual-core, ma non trarrebbe vantaggio da più di 4 thread su un computer quad-core. Se la quantità di informazioni che è necessario comunicare è bassa, il multiprocessing potrebbe avere più senso.

Per quanto riguarda lo stile di youtube che hai descritto, direi che suggerisce il multiprocessing. Se si seguono approcci MVC, la GUI non deve contenere anche il modello (risultato del calcolo). Con il multiprocesso, è possibile quindi comunicare a un responsabile del lavoro che può segnalare quali dati sono già disponibili.

+0

"i processi possono condividere la stessa memoria in modalità di sola lettura" Penso che sarà molto utile per me. Come lo faccio? –

+0

Sulla maggior parte dei sistemi UNIX, quando si esegue il fork di un processo (crea uno dall'altro), devono condividere le stesse pagine di lettura finché non scrivono. Salva il caricamento del codice del programma. Ma non è così utile come tecnica di programmazione. – Uri

+0

Sfortunatamente, su Windows non è questo il caso (Windows non ha os.fork disponibile). –

14

Quest'anno si è parlato bene di multiprocessing a Pycon.Il messaggio da asporto era "Usa la multiprocessing solo se sei sicuro di avere un problema che risolverà, che non può essere risolto con i thread, altrimenti usa i thread."

I processi hanno molti overhead e tutti i dati da condividere tra i processi devono essere serializzabili (cioè selezionabili).

È possibile visualizzare le diapositive e video qui: http://blip.tv/pycon-us-videos-2009-2010-2011/introduction-to-multiprocessing-in-python-1957019

http://us.pycon.org/2009/conference/schedule/event/31/

+3

Questo è un peccato, perché è quasi l'opposto di quello che faresti in altre lingue, ove possibile. I thread sono soggetti a errori e limitati rispetto ai processi, e in Python si ottiene il problema GIL per aggiungere la beffa al danno. – Kylotan

+9

mentre è vero che più processi hanno un piccolo sovraccarico di runtime (anche se è molto meno vero di cinque o dieci anni fa), il codice threaded ha una quantità enorme di overhead di programmazione. Ci vogliono persone intelligenti per scrivere un buon codice thread e persone molto intelligenti per eseguirne il debug. –

+1

C'è un collegamento aggiornato a queste diapositive/parla? Il link corrente sembra essere inattivo. – Tyler

0

Sembra che ci si vuole threading.

Il modo in cui l'hai descritto, sembrava che ci fosse una sola cosa che in realtà richiedeva un sacco di CPU ... l'esecuzione effettiva della simulazione.

Quello che stai cercando di ottenere è un display più reattivo, consentendo l'interazione dell'utente e gli aggiornamenti grafici mentre la simulazione è in esecuzione. Questo è esattamente ciò per cui è stata creata la filettatura di Python.

Ciò che NON otterrete è la possibilità di usufruire di più core/processori sul vostro sistema. Non ho idea di come sia la tua simulazione, ma se è così intensa per la CPU, potrebbe essere un buon candidato per la suddivisione. In questo caso, è possibile utilizzare il multiprocessing per eseguire parti separate della simulazione su core/processori separati. Tuttavia, questo non è banale ... ora è necessario un modo per passare i dati indietro e il quarto tra i processi, in quanto i processi separati non possono accedere facilmente allo stesso spazio di memoria.

4

Se si desidera leggere una lunga discussione sul multi-threading in Mozilla, prendere in considerazione lo this discussion avviato nel 2000. La discussione non risponde necessariamente alla domanda. Tuttavia, è una discussione approfondita che ritengo sia interessante e informativa, che suggerisco possa essere abbastanza valida perché hai posto una domanda difficile. Spero che ti aiuterà a prendere una decisione informata.

Incidentalmente, diversi membri del progetto Mozilla (in particolare Brendan Eich, CTO di Mozilla e creatore di JavaScript) erano piuttosto critici nei confronti del multi-threading in particolare. Parte del materiale di riferimento here, here, here e here supporta tale conclusione.

Spero che ti aiuti e buona fortuna.

1

Molto perplesso. Bastien Léonard ha giustamente sottolineato che il GIL fermerà qualsiasi possibilità di usare il threading in qualsiasi modo utile. I suoi stati di riferimento:

"Utilizzo di una serratura interprete globale in una lingua limita efficacemente la quantità di parallelismo raggiungibile attraverso la concorrenza di un unico processo interprete con più thread Se il processo è quasi puramente composto da. codice interpretato e non effettua chiamate all'esterno dell'interprete per lunghi periodi di tempo (che può rilasciare il blocco sul GIL su quel thread mentre viene elaborato), è probabile che sia molto poco aumento di velocità durante l'esecuzione del processo su una macchina multiprocessore . A causa della segnalazione con una filettatura legata alla CPU, è possibile impostare causare un rallentamento significativo, anche sui singoli processori. "

In questo caso, la multielaborazione è quindi la scelta giusta.Dalla mia esperienza personale, Python + MT non ha alcun beneficio apprezzabile per l'utente.