Cosa possono fare più thread che un singolo thread non può fare? [chiuso]


101

Mentre i thread possono accelerare l'esecuzione del codice, sono effettivamente necessari? Ogni pezzo di codice può essere fatto usando un singolo thread o esiste qualcosa che può essere realizzato solo usando più thread?


29
Sulla base di alcune delle risposte già pubblicate qui, penso che alcuni chiarimenti siano in ordine. Lo scopo del threading è consentire ai computer di (sembra) fare più di una cosa alla volta. Se questo viene fatto utilizzando un computer con un singolo core, non vedrai alcun eccesso di velocità generale. Quello che vedrai è sbloccarsi; in un programma a thread singolo, l'interfaccia utente verrà bloccata durante l'esecuzione dei calcoli. In un programma multi-thread, l'interfaccia utente può essere ancora utilizzabile mentre i calcoli avvengono in background.
Robert Harvey,

11
Ovviamente, se nel tuo computer sono presenti più core del processore (cosa al giorno d'oggi comune), il tuo programma può utilizzare i thread per sfruttare i core aggiuntivi per eseguire l'elaborazione, e vedrai un aumento di velocità, perché stai lanciando più cavalli a il tuo problema informatico. Se non usi affatto i thread, il tuo programma utilizzerà solo un singolo core del processore, il che va bene se è tutto ciò di cui hai bisogno.
Robert Harvey,

14
Un programma a thread singolo non può deadlockare le risorse come può fare un programma a thread multipli.
zzzzBov

3
Risposta: corri su due core
Daniel Little il

6
Risposta: causare un deadlock.
Giobbe

Risposte:


112

Prima di tutto, i thread non possono accelerare l'esecuzione del codice. Non rendono il computer più veloce. Tutto ciò che possono fare è aumentare l'efficienza del computer utilizzando il tempo che altrimenti verrebbe sprecato. In alcuni tipi di elaborazione questa ottimizzazione può aumentare l'efficienza e ridurre il tempo di esecuzione.

La semplice risposta è sì. Puoi scrivere qualsiasi codice da eseguire su un singolo thread. Prova: un sistema a singolo processore può eseguire le istruzioni in modo lineare. Avere più linee di esecuzione viene eseguito dagli interrupt di elaborazione del sistema operativo, salvando lo stato del thread corrente e avviandone un altro.

La risposta complessa è ... più complessa! La ragione per cui i programmi multithread possono essere spesso più efficienti di quelli lineari è a causa di un "problema" hardware. La CPU è in grado di eseguire calcoli più rapidamente rispetto alla memoria e all'IO della memoria effettiva. Pertanto, un'istruzione "add", ad esempio, viene eseguita molto più rapidamente di un "fetch". Le cache e il recupero delle istruzioni del programma dedicato (non sono sicuro del termine esatto qui) possono contrastare questo in una certa misura, ma il problema di velocità rimane.

Il threading è un modo per combattere questa discrepanza utilizzando la CPU per le istruzioni associate alla CPU mentre le istruzioni IO sono in fase di completamento. Un tipico piano di esecuzione del thread sarebbe probabilmente: recuperare dati, elaborare dati, scrivere dati. Supponiamo che il recupero e la scrittura richiedano 3 cicli e l'elaborazione richieda uno, a scopo illustrativo. Potete vedere che mentre il computer sta leggendo o scrivendo, non sta facendo nulla per 2 cicli ciascuno? Chiaramente è pigro e dobbiamo schioccare la nostra frusta di ottimizzazione!

Possiamo riscrivere il processo usando il threading per usare questo tempo sprecato:

  1. Recupero n. 1
  2. nessuna operazione
  3. Recupero # 2
  4. # 1 fatto, elaboralo
  5. scrivi # 1
  6. Recupero n. 1
  7. # 2 è fatto, elaboralo
  8. scrivi # 2
  9. prendere # 2

E così via. Ovviamente questo è un esempio un po 'inventato, ma puoi vedere come questa tecnica può utilizzare il tempo che altrimenti verrebbe speso in attesa di IO.

Si noti che il threading come mostrato sopra può solo aumentare l'efficienza su processi fortemente legati all'IO. Se un programma calcola principalmente le cose, non ci saranno molti "buchi" in cui potremmo fare più lavoro. Inoltre, ci sono molte istruzioni per passare da un thread all'altro. Se si eseguono troppi thread, la CPU impiegherà la maggior parte del tempo a passare e non funziona molto sul problema. Questo si chiama thrashing .

Che tutto vada bene per un processore single core, ma la maggior parte dei processori moderni ha due o più core. I thread hanno ancora lo stesso scopo: massimizzare l'utilizzo della CPU, ma questa volta abbiamo la possibilità di eseguire due istruzioni separate contemporaneamente. Ciò può ridurre il tempo di esecuzione di un fattore per quanto siano disponibili molti core, poiché il computer è in realtà multitasking, non commutazione di contesto.

Con più core, i thread forniscono un metodo per dividere il lavoro tra i due core. Quanto sopra vale comunque per ogni singolo core; Un programma che esegue una massima efficienza con due thread su un core funzionerà molto probabilmente alla massima efficienza con circa quattro thread su due core. (L'efficienza è misurata qui con esecuzioni minime dell'istruzione NOP.)

I problemi con l'esecuzione di thread su più core (al contrario di un singolo core) sono generalmente risolti dall'hardware. La CPU sarà sicura di bloccare le posizioni di memoria appropriate prima di leggere / scrivere su di essa. (Ho letto che utilizza un bit di flag speciale in memoria per questo, ma questo potrebbe essere realizzato in diversi modi.) Come programmatore con linguaggi di livello superiore, non devi preoccuparti di nulla di più su due core come te avrebbe dovuto con uno.

TL; DR: i thread possono dividere il lavoro in modo da consentire al computer di elaborare diverse attività in modo asincrono. Ciò consente al computer di funzionare alla massima efficienza utilizzando tutto il tempo di elaborazione disponibile, anziché bloccarsi quando un processo è in attesa di una risorsa.


17
Risposta eccellente. Volevo solo chiarire che dopo un certo punto, l'aggiunta di più thread può effettivamente rallentare l' esecuzione di un programma , poiché viene utilizzato tutto il tempo precedentemente "sprecato" e ora si stanno solo aggiungendo ulteriori switch di contesto e sovraccarico di sincronizzazione.
Karl Bielefeldt,

8
+1 per descrivere come i thread aiutano con l'elaborazione del blocco IO. Un altro uso dei thread è consentire all'interfaccia utente di continuare a elaborare le azioni dell'utente (movimento del mouse, barre di avanzamento, sequenze di tasti) in modo che la percezione dell'utente sia che il programma non si sia "congelato".
jqa,

3
Un'altra aggiunta: a rigor di termini, i thread non aggiungono espressività alla maggior parte delle lingue; potresti, se assolutamente necessario, implementare tutto il multiplexing da solo e ottenere gli stessi risultati. In pratica, ciò equivarrebbe a reimplementare l'intera libreria di threading, proprio come la ricorsione non è strettamente necessaria, ma può essere emulata scrivendo il proprio stack di chiamate.
Kilian Foth,

9
@james: classificherei l'elaborazione dell'interfaccia utente come solo un'altra forma di I / O. Forse il peggio, poiché gli utenti tendono ad essere ritardati e non lineari. :)
TMN

7
C'è un presupposto silenzioso nella domanda e risposta intorno al computer che è single core o CPU. Il mio orologio ha due core, dubito che l'ipotesi sia valida su qualsiasi macchina moderna.
blueberryfields

38

Cosa possono fare più thread che un singolo thread non può fare?

Niente.

Schizzo di prova semplice:

  • [Congettura di Church-Turing] ⇒ Tutto ciò che può essere calcolato può essere calcolato da una Universal Turing Machine.
  • Una macchina di Turing universale è a filettatura singola.
  • Ergo, tutto ciò che può essere calcolato può essere calcolato da un singolo thread.

Si noti, tuttavia, che c'è un grande presupposto nascosto lì dentro: vale a dire che il linguaggio utilizzato all'interno del singolo thread è Turing-completo.

Quindi, la domanda più interessante potrebbe essere: "Può l'aggiunta di solo multi-threading per una lingua non-Turing-complete renderlo Turing-completo?" E credo che la risposta sia "Sì".

Prendiamo i linguaggi funzionali totali. [Per chi non ha familiarità: proprio come la programmazione funzionale è la programmazione con funzioni, la programmazione funzionale totale è la programmazione con funzioni totali.]

I linguaggi funzionali totali non sono ovviamente completi di Turing: non è possibile scrivere un ciclo infinito in un TFPL (in effetti, è praticamente la definizione di "totale"), ma è possibile in una macchina di Turing, ergo esiste almeno un programma che non può essere scritto in un TFPL ma può essere in un UTM, pertanto i TFPL sono meno potenti dal punto di vista computazionale degli UTM.

Tuttavia, non appena aggiungi il threading a un TFPL, ottieni infiniti loop: esegui ogni iterazione del loop in un nuovo thread. Ogni singolo thread restituisce sempre un risultato, quindi è Totale, ma ogni thread genera anche un nuovo thread che esegue la successiva iterazione, all'infinito.

Io penso che questa lingua sarebbe Turing-completo.

Per lo meno, risponde alla domanda originale:

Cosa possono fare più thread che un singolo thread non può fare?

Se si dispone di una lingua che non può fare un loop infinito, allora il multi-threading permette di fare cicli infiniti.

Nota, ovviamente, che la generazione di un thread è un effetto collaterale e quindi il nostro linguaggio esteso non è solo non più totale, non è nemmeno più funzionale.


13
Da quando hai sollevato una "prova", non posso impedirmi di "bene, in realtà ..." ing. Penso che tu stia abusando della nozione di calcolabilità. La prova è una cosa carina e capisco bene, ma non è proprio al livello di astrazione giusto. Non essere in grado di fare le cose non è lo stesso di non essere in grado di calcolare , ad esempio, non è possibile utilizzare la prova per dire, perché la macchina di Turing può calcolare "ogni funzione calcolabile", può farlo in 3 secondi. A rigor di termini, una singola macchina threaded senza interruzioni non può accedere all'I / O mentre il suo processore è impegnato a eseguire il calcolo.
xmm0

1
E nessun vero computer è una macchina di Turing.
Jens,

1
@ColeJohnson: un deadlock è un dettaglio di implementazione. L'output visibile è "non arrestarsi", il che è facilmente realizzabile con un singolo thread.
Heinzi,

1
@Heinzi: "facilmente realizzabile" è un eufemismo. Se ricordo bene, il secondo o il terzo programma che ho mai scritto ha fatto esattamente questo! ;-)
Joachim Sauer,

1
Se l'universo è a thread singolo , allora cos'è la teoria delle stringhe ? Non puoi discutere con la scienza in questo modo.
corsiKa

22

In teoria, tutto ciò che fa un programma multithread può essere fatto anche con un programma a thread singolo, solo più lentamente.

In pratica, la differenza di velocità potrebbe essere così grande che non è possibile utilizzare un programma a thread singolo per l'attività. Ad esempio, se hai un processo di elaborazione dei dati batch in esecuzione ogni notte e ci vogliono più di 24 ore per terminare su un singolo thread, non hai altra opzione che renderlo multithread. (In pratica, la soglia è probabilmente anche inferiore: spesso tali attività di aggiornamento devono terminare entro la mattina presto, prima che gli utenti inizino a utilizzare nuovamente il sistema. Inoltre, altre attività possono dipendere da esse, che devono terminare anche nella stessa notte. l'autonomia disponibile può essere di poche ore / minuti.)

Fare lavoro di calcolo su più thread è una forma di elaborazione distribuita; stai distribuendo il lavoro su più thread. Un altro esempio di elaborazione distribuita (utilizzando più computer anziché più thread) è lo screensaver SETI: sgranocchiare che molti dati di misurazione su un singolo processore richiederebbe un tempo terribile e i ricercatori preferirebbero vedere i risultati prima del pensionamento ;-) Tuttavia, hanno non hanno il budget per affittare un supercomputer per così tanto tempo, quindi distribuiscono il lavoro su milioni di PC domestici, per renderlo economico.


Lo screensaver SETI è un esempio di threading nel senso che viene eseguito su un thread in background nel tuo computer; sei ancora in grado di fare altre cose sul tuo computer mentre esegue lo scricchiolio dei dati in background. Senza il thread, ci sarebbe una pausa mentre lo screensaver SETI esegue i suoi calcoli; dovresti aspettare che finisca prima di poter continuare il tuo lavoro.
Robert Harvey,

3
@Robert: Penso che Péter stia usando SETI @ Home per spiegare il concetto di suddividere il lavoro da eseguire su più processori. Il calcolo distribuito è ovviamente diverso dal multithreading, ma il concetto è simile.
Steven

5
Penso che l'esempio SETI sia il calcolo distribuito piuttosto che il multi-thread. Concetti simili ma non la stessa cosa.

11

Sebbene i thread sembrino essere un piccolo passo dal calcolo sequenziale, in realtà rappresentano un enorme passo. Scartano le proprietà più essenziali e attraenti del calcolo sequenziale: comprensibilità, prevedibilità e determinismo. I thread, come modello di calcolo, sono selvaggiamente non deterministici, e il lavoro del programmatore diventa quello di potare quel non determinismo.

- The Problem with Threads (www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf).

Mentre ci sono alcuni vantaggi prestazionali che si possono ottenere usando i thread in quanto è possibile distribuire il lavoro su più core, spesso hanno un ottimo prezzo.

Uno degli svantaggi dell'utilizzo di thread non ancora menzionati qui è la perdita di compartimentazione delle risorse che si ottiene con spazi di processo a thread singolo. Ad esempio, supponiamo di imbattersi nel caso di un segfault. In alcuni casi è possibile riprendersi da questo in un'applicazione multi-processo in quanto si lascia semplicemente morire il bambino in errore e ne si respinge uno nuovo. Questo è il caso del backend prefork di Apache. Quando un'istanza httpd va a gonfie vele, il caso peggiore è che la particolare richiesta HTTP può essere ignorata per quel processo, ma Apache genera un nuovo figlio e spesso la richiesta se appena rinviata e revisionata. Il risultato finale è che Apache nel suo insieme non viene rimosso con il thread difettoso.

Un'altra considerazione in questo scenario sono le perdite di memoria. Ci sono alcuni casi in cui è possibile gestire con grazia un crash del thread (su UNIX, è possibile il recupero da alcuni segnali specifici - anche segfault / fpviolation -), ma anche in quel caso, è possibile che sia trapelata tutta la memoria allocata da quel thread (malloc, nuovo, ecc.). Quindi, mentre il processo può continuare a funzionare, perde sempre più memoria nel tempo ad ogni errore / ripristino. Ancora una volta, ci sono in qualche modo modi per minimizzare questo come l'uso di pool di memoria da parte di Apache. Ma ciò non protegge ancora dalla memoria che potrebbe essere stata allocata dalle librerie di terze parti che il thread potrebbe aver utilizzato.

E, come alcune persone hanno sottolineato, comprendere le primitive di sincronizzazione è forse la cosa più difficile da ottenere davvero. Questo problema di per sé - solo ottenere la logica generale giusta per tutto il codice - può essere un grosso mal di testa. È possibile che si verifichino deadlock misteriosi nei momenti più strani, e talvolta nemmeno fino a quando il programma non è stato avviato in produzione, il che rende il debug ancora più difficile. Aggiungete a ciò il fatto che le primitive di sincronizzazione variano spesso ampiamente con la piattaforma (Windows vs. POSIX) e il debug può essere spesso più difficile, nonché la possibilità di condizioni di gara in qualsiasi momento (avvio / inizializzazione, runtime e spegnimento), la programmazione con thread ha davvero poca pietà per i principianti. E anche per esperti, c'è ancora poca misericordia solo perché la conoscenza del threading stesso non minimizza la complessità in generale. Ogni riga di codice threaded sembra talvolta aggravare in modo esponenziale la complessità complessiva del programma e aumentare la probabilità che emergano in qualsiasi momento un deadlock nascosto o una strana condizione di razza. Può anche essere molto difficile scrivere casi di prova per scovare queste cose.

Questo è il motivo per cui alcuni progetti come Apache e PostgreSQL sono per lo più basati su processi. PostgreSQL esegue ogni thread back-end in un processo separato. Naturalmente questo non allevia ancora il problema della sincronizzazione e delle condizioni di gara, ma aggiunge un bel po 'di protezione e in qualche modo semplifica le cose.

Più processi ciascuno che esegue un singolo thread di esecuzione può essere molto meglio di più thread in esecuzione in un singolo processo. E con l'avvento di gran parte del nuovo codice peer-to-peer come AMQP (RabbitMQ, Qpid, ecc.) E ZeroMQ, è molto più semplice dividere i thread tra diversi spazi di processo e persino macchine e reti, semplificando notevolmente le cose. Ma comunque, non è un proiettile d'argento. C'è ancora complessità da affrontare. Basta spostare alcune delle variabili dallo spazio del processo alla rete.

La linea di fondo è che la decisione di entrare nel dominio dei thread non è leggera. Una volta che ti avventuri in quel territorio, quasi istantaneamente tutto diventa più complesso e intere nuove razze di problemi entrano nella tua vita. Può essere divertente e bello, ma è come l'energia nucleare - quando le cose vanno male, possono andare male e velocemente. Ricordo di aver seguito un corso di addestramento sulla criticità molti anni fa e hanno mostrato le foto di alcuni scienziati di Los Alamos che hanno suonato con il plutonio nei laboratori della seconda guerra mondiale. Molti hanno preso poche o nessuna precauzione contro l'evento di un'esposizione e in un batter d'occhio - in un singolo lampo luminoso e indolore, tutto sarebbe finito per loro. Giorni dopo erano morti. Richard Feynman in seguito si riferì a questo come " solleticare la coda del drago"È un po 'come giocare ai thread (almeno per me comunque). All'inizio sembra piuttosto innocuo, e quando ti mordi, ti gratti la testa con la velocità con cui le cose sono andate male. Ma almeno i thread hanno vinto ti uccido.


La mia risposta TL; DR impallidisce rispetto a questo bel pezzo su ciò che i singoli thread non faranno per te.
bmike

1
pausa caffè pomeridiana
Mike Owens,

10

Innanzitutto, un'applicazione a thread singolo non trarrà mai vantaggio da una CPU multi-core o da hyper-threading. Ma anche su un singolo core, la CPU a thread singolo che esegue il multi-threading presenta vantaggi.

Considera l'alternativa e se ciò ti rende felice. Supponiamo di avere più attività che devono essere eseguite contemporaneamente. Ad esempio, devi continuare a comunicare con due diversi sistemi. Come si fa senza multi-threading? Probabilmente dovresti creare il tuo programmatore e lasciarlo chiamare le diverse attività che devono essere eseguite. Ciò significa che è necessario suddividere le attività in parti. Probabilmente è necessario soddisfare alcuni vincoli in tempo reale e assicurarsi che le parti non impieghino troppo tempo. Altrimenti il ​​timer scadrà in altre attività. Questo rende più difficile dividere un'attività. Più attività devi gestire, più suddivisione devi svolgere e più complessa sarà la tua pianificazione per soddisfare tutti i vincoli.

Quando hai più thread, la vita può diventare più semplice. Uno scheduler preventivo può interrompere un thread in qualsiasi momento, mantenerne lo stato e riavviarne un altro. Si riavvierà quando il tuo thread inizia il suo turno. Vantaggi: la complessità di scrivere uno scheduler è già stata fatta per te e non devi dividere i tuoi compiti. Inoltre, lo scheduler è in grado di gestire processi / thread di cui non sei nemmeno a conoscenza. Inoltre, quando un thread non ha bisogno di fare nulla (è in attesa di un evento) non richiede cicli di CPU. Questo non è così facile da realizzare quando si crea lo scheduler down a thread singolo. (mettere a dormire qualcosa non è così difficile, ma come si sveglia?)

Il rovescio della medaglia dello sviluppo multi-thread è che è necessario conoscere i problemi di concorrenza, le strategie di blocco e così via. Lo sviluppo di codice multi-thread senza errori può essere piuttosto difficile. E il debug può essere ancora più difficile.


9

esiste qualcosa che può essere realizzato solo usando più thread?

Sì. Non è possibile eseguire codice su più CPU o core della CPU con un singolo thread.

Senza più CPU / core, i thread possono ancora semplificare il codice che viene eseguito concettualmente in parallelo, come la gestione dei client su un server, ma è possibile fare la stessa cosa senza thread.


6

Le discussioni non riguardano solo la velocità ma anche la concorrenza.

Se non hai un'applicazione batch come suggerito da @Peter ma invece un toolkit GUI come WPF come puoi interagire con gli utenti e la logica aziendale con un solo thread?

Supponiamo inoltre di creare un server Web. Come servirebbe più di un utente contemporaneamente con un solo thread (supponendo che nessun altro processo)?

Esistono molti scenari in cui un solo thread semplice non è sufficiente. Ecco perché sono in corso recenti progressi come il processore Intel MIC con oltre 50+ core e centinaia di thread.

Sì, la programmazione parallela e simultanea è difficile. Ma necessario.


3
"Solo un thread" può significare diverse cose: ad esempio, è possibile utilizzare continuazioni delimitate per simulare il multitasking cooperativo all'interno di un singolo thread (sistema operativo o verde).
Frank Shearar,

Certo, ma sto dando un piccolo contesto alla domanda @ Frank +1 per il suggerimento.
Randolf Rincón Fadul,

3
I thread possono renderlo più semplice, ma tutte le attività che hai citato possono essere eseguite senza thread e in effetti lo erano. Ad esempio, il loop della GUI canonica era in passato while (true) {process GUI events; calcola un po '}. Nessun thread necessario.
KeithB

Esistono server Web a thread singolo a processo singolo. lighttpd ad esempio, o thttpd o nginx (sebbene quest'ultimo possa eseguire più di un processo, ma il valore predefinito è uno. Inoltre è sempre a thread singolo). Non hanno assolutamente problemi a servire più di un utente.
StasM,

6

Il multi-threading può rendere l'interfaccia della GUI ancora reattiva durante le lunghe operazioni di elaborazione. Senza il multi-threading, l'utente sarebbe bloccato a guardare un modulo bloccato mentre è in esecuzione un processo lungo.


Non è del tutto corretto. In teoria, potresti dividere la tua lunga operazione in molte più piccole e aggiornare l'elaborazione degli eventi in mezzo.
Sebastian Negraszus,

@Sebastion N. Ma se il processo lungo non può essere trasformato in processi più piccoli? La possibilità di eseguire il processo in un altro thread può liberare il thread della GUI (il thread principale) per essere ancora reattivo.
LarsTech,

5

Il codice multi-thread può bloccare la logica del programma e accedere ai dati non aggiornati in modi impossibili per i singoli thread.

I thread possono prendere un bug oscuro da qualcosa che un programmatore medio può aspettarsi di eseguire il debug e spostarlo nel regno in cui vengono raccontate storie della fortuna necessaria per catturare lo stesso bug con i pantaloni quando un programmatore di allarme stava guardando solo il momento giusto.


4

le app che si occupano del blocco degli I / O che devono anche rimanere sensibili ad altri input (la GUI o altre connessioni) non possono essere rese singlethreaded

l'aggiunta di metodi di controllo nella libreria IO per vedere quanto può essere letto senza bloccare può aiutare questo, ma non molte librerie offrono garanzie complete a riguardo


Possono essere a thread singolo (e spesso lo erano). Il codice dice al kernel di avviare un po 'di IO e riceve un segnale quando viene completato. Durante l'attesa del segnale, può eseguire altre elaborazioni.
KeithB

@keith che è IO non bloccante, ho detto specificamente il blocco
maniaco del cricchetto

Ma perché dovresti bloccare l'IO se vuoi rimanere reattivo? Esiste un IO bloccante che generalmente non ha un'alternativa non bloccante? Non riesco a pensare a nessuno.
KeithB

L'RMI di @keith java sta bloccando e mentre è possibile implementare un callback (ma che crea un altro thread) con esso ma che può essere bloccato dai firewall
maniaco del cricco

Sembra una limitazione dell'RMI Java, non una limitazione intrinseca del codice a thread singolo. Inoltre, se stai eseguendo RMI hai un "thread" separato di esecuzione, proprio su una macchina remota.
KeithB

4

Molte buone risposte, ma non sono sicuro che una frase sia esattamente come farei - Forse questo offre un modo diverso di vederlo:

I thread sono solo una semplificazione della programmazione come Oggetti o Attori o per i loop (Sì, tutto ciò che si implementa con i loop che è possibile implementare con if / goto).

Senza thread si implementa semplicemente un motore di stato. Ho dovuto farlo molte volte (la prima volta che l'ho fatto non ne avevo mai sentito parlare - ho appena fatto una grande dichiarazione switch controllata da una variabile "State"). Le macchine a stati sono ancora abbastanza comuni ma possono essere fastidiose. Con i fili, un enorme pezzo della piastra della caldaia scompare.

Capita anche che sia più facile per un linguaggio interrompere la sua esecuzione in runtime in blocchi compatibili con più CPU (anche gli attori, credo).

Java fornisce thread "verdi" su sistemi in cui il sistema operativo non fornisce QUALSIASI supporto di threading. In questo caso è più facile vedere che chiaramente non sono altro che un'astrazione di programmazione.


+1 - I thread forniscono solo un'astrazione per il parallelismo su macchine sostanzialmente sequenziali, proprio come i linguaggi di programmazione di alto livello forniscono un'astrazione del codice macchina.
mouviciel,

0

Il sistema operativo utilizza il concetto di suddivisione del tempo in cui ogni thread ottiene il tempo di essere eseguito e quindi viene annullato. Un approccio del genere può sostituire il threading così com'è ora, ma scrivere i propri programmatori in ogni applicazione sarebbe eccessivo. Inoltre, dovresti lavorare con i dispositivi I / O e così via. E richiederebbe un po 'di supporto dal lato hardware, in modo da poter attivare gli interrupt per far funzionare lo scheduler. Fondamentalmente dovresti scrivere un nuovo sistema operativo ogni volta.

In generale, il threading può migliorare le prestazioni nei casi in cui i thread attendono l'I / O o sono inattivi. Consente inoltre di creare interfacce reattive e di interrompere i processi mentre si eseguono attività lunghe. Inoltre, il threading migliora le cose su CPU multicore reali.


0

Innanzitutto, i thread possono fare due o più cose contemporaneamente (se hai più di un core). Sebbene sia possibile farlo anche con più processi, alcune attività non si distribuiscono molto bene su più processi.

Inoltre, in alcune attività sono presenti spazi che non è possibile evitare facilmente. Ad esempio, è difficile leggere i dati da un file su disco e fare in modo che il processo faccia qualcos'altro allo stesso tempo. Se l'attività richiede necessariamente molti dati di lettura dal disco, il processo impiegherà molto tempo ad aspettare il disco, qualunque cosa tu faccia.

In secondo luogo, i thread possono consentirti di evitare di dover ottimizzare grandi quantità di codice che non è critico per le prestazioni. Se hai un solo thread, ogni pezzo di codice è critico per le prestazioni. Se si blocca, sei affondato: nessuna attività che verrebbe eseguita da quel processo può fare progressi. Con i thread, un blocco influisce solo sul fatto che il thread e altri thread possono venire avanti e lavorare su attività che devono essere eseguite da quel processo.

Un buon esempio è il codice di gestione degli errori eseguito di rado. Supponiamo che un'attività rilevi un errore molto raro e che il codice per gestirlo debba scorrere nella memoria. Se il disco è occupato e il processo ha solo un singolo thread, non è possibile eseguire progressi in avanti fino a quando il codice per gestire quell'errore non può essere caricato in memoria. Ciò può causare una risposta affrettata.

Un altro esempio è se molto raramente è necessario eseguire una ricerca nel database. Se aspetti che il database risponda, il tuo codice colpirà un enorme ritardo. Ma non vuoi preoccuparti di rendere tutto questo codice asincrono perché è così raro che devi fare queste ricerche. Con un thread per fare questo lavoro, ottieni il meglio da entrambi i mondi. Un thread per fare questo lavoro lo rende non critico come dovrebbe essere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.