Domanda

Quali sono le differenze tra una "coroutine" e un "thread"?

È stato utile?

Soluzione

coroutine sono una forma di elaborazione sequenziale: solo queste è in esecuzione in un dato momento (come procedure subroutine AKA AKA funzioni - hanno appena passano il testimone tra loro in modo più fluido).

Filati sono (almeno concettualmente) un modulo di elaborazione simultanea: più thread possono essere in esecuzione in un dato momento. (Tradizionalmente, il singolo-CPU, macchine single-core, che la concorrenza è stata simulata con qualche aiuto dal sistema operativo - al giorno d'oggi, dal momento che così molte macchine sono multi-CPU e / o multi-core, le discussioni saranno de facto essere in esecuzione contemporaneamente, non solo "concettualmente").

Altri suggerimenti

Prima lettura: Concorrenza vs Parallelismo: qual è la differenza?

La concorrenza è la separazione di compiti per fornire esecuzione intercata.Il parallelismo è l'esecuzione simultanea di più lavori per aumentare la velocità.—https://github.com/servo/servo/wiki/Design

Risposta breve: Con i thread, il sistema operativo commuta preventivamente i thread in esecuzione in base al proprio scheduler, che è un algoritmo nel kernel del sistema operativo.Con le coroutine, il programmatore e il linguaggio di programmazione determinano quando cambiare coroutine;in altre parole, le attività vengono svolte in multitasking in modo cooperativo mettendo in pausa e riprendendo le funzioni in punti prestabiliti, tipicamente (ma non necessariamente) all'interno di un singolo thread.

Risposta lunga: A differenza dei thread, che vengono pianificati preventivamente dal sistema operativo, i cambi di coroutine sono cooperativi, nel senso che il programmatore (e possibilmente il linguaggio di programmazione e il suo runtime) controlla quando avverrà un cambio.

Contrariamente ai thread, che sono preventivi, gli switch di coroutine sono cooperativi (i controlli del programmatore quando si verificherà un interruttore).Il kernel non è coinvolto negli switch di coroutine.—http://www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html/coroutine/overview.html

Una lingua che sostiene thread nativi può eseguire i suoi thread (thread utente) sui thread del sistema operativo (thread del kernel).Ogni processo ha almeno un thread del kernel.I thread del kernel sono come i processi, tranne per il fatto che condividono lo spazio di memoria nel processo proprietario con tutti gli altri thread in quel processo.Un processo "possiede" tutte le risorse assegnate, come memoria, handle di file, socket, handle di dispositivo, ecc., e queste risorse sono tutte condivise tra i suoi thread del kernel.

Lo scheduler del sistema operativo è parte del kernel che esegue ciascun thread per un certo periodo di tempo (su una macchina a processore singolo).Lo scheduler assegna tempo (timeslicing) a ciascun thread e, se il thread non viene terminato entro quel tempo, lo scheduler lo anticipa (lo interrompe e passa a un altro thread).Più thread possono essere eseguiti in parallelo su una macchina multiprocessore, poiché ogni thread può essere (ma non deve essere necessariamente) pianificato su un processore separato.

Su una macchina a processore singolo, i thread vengono suddivisi in time-slice e preempted (passati da uno all'altro) rapidamente (su Linux il time-slice predefinito è 100 ms), il che li rende simultanei.Tuttavia, non possono essere eseguiti in parallelo (simultaneamente), poiché un processore single-core può eseguire solo una cosa alla volta.

Coroutine e/o generatori può essere utilizzato per implementare funzioni cooperative.Invece di essere eseguiti sui thread del kernel e pianificati dal sistema operativo, vengono eseguiti in un singolo thread finché non cedono o finiscono, cedendo ad altre funzioni determinate dal programmatore.Lingue con generatori, come Python ed ECMAScript 6, possono essere utilizzati per creare coroutine.Async/await (visto in C#, Python, ECMAscript 7, Rust) è un'astrazione costruita su funzioni del generatore che producono futuri/promesse.

In alcuni contesti, coroutine può riferirsi a funzioni stackful while generatori può riferirsi a funzioni stackless.

Fibre, fili leggeri, E fili verdi sono altri nomi per coroutine o cose simili a coroutine.A volte possono assomigliare (tipicamente di proposito) più ai thread del sistema operativo nel linguaggio di programmazione, ma non funzionano in parallelo come i thread reali e funzionano invece come coroutine.(Potrebbero esserci particolarità tecniche o differenze più specifiche tra questi concetti a seconda della lingua o dell'implementazione.)

Ad esempio, Java aveva "fili verdi";si trattava di thread pianificati dalla Java virtual machine (JVM) anziché in modo nativo sui thread del kernel del sistema operativo sottostante.Questi non funzionavano in parallelo né sfruttavano più processori/core, poiché ciò richiederebbe un thread nativo!Poiché non erano pianificati dal sistema operativo, erano più simili a coroutine che a thread del kernel.I thread verdi sono quelli utilizzati da Java fino all'introduzione dei thread nativi in ​​Java 1.2.

I thread consumano risorse.Nella JVM, ogni thread ha il proprio stack, in genere di 1 MB.64k è la quantità minima di spazio stack consentita per thread nella JVM.La dimensione dello stack di thread può essere configurata sulla riga di comando per la JVM.Nonostante il nome, i thread non sono gratuiti, a causa del loro utilizzo di risorse, ad esempio ogni thread che necessita del proprio stack, dell'archiviazione locale del thread (se presente) e del costo della pianificazione dei thread/cambio di contesto/invalidazione della cache della CPU.Questo è uno dei motivi per cui le coroutine sono diventate popolari per applicazioni altamente simultanee e critiche in termini di prestazioni.

Mac OS consentirà a un processo di allocare solo circa 2000 thread, mentre Linux allocherà uno stack di 8 MB per thread e consentirà solo il numero di thread che si adatterà alla RAM fisica.

Pertanto, i thread hanno il peso maggiore (in termini di utilizzo della memoria e tempo di cambio di contesto), quindi le coroutine e infine i generatori sono il peso più leggero.

Circa 7 anni di ritardo, ma le risposte qui mancano un contesto in co-routine vs discussioni. Perché coroutine che riceve così tanta attenzione ultimamente, e quando avrei usarli rispetto a discussioni

Prima di tutto se coroutine corrono in concomitanza (mai in parallelo ), perché qualcuno li preferirebbe nel corso discussioni?

La risposta è che coroutine possono fornire una molto elevata concorrenza con molto poco overhead . In generale, in un ambiente filettato avete al massimo 30-50 le discussioni prima che la quantità di overhead sprecati in realtà la pianificazione di questi fili (dallo scheduler di sistema) significativamente tagli nella quantità di tempo che i fili in realtà fanno un lavoro utile.

Ok, quindi con i fili si può avere il parallelismo, ma non troppo il parallelismo, non è che ancora meglio di una corsa co-di routine in un singolo thread? Beh, non necessariamente. Ricorda un co-routine può ancora fare concorrenza senza scheduler in testa -. Gestisce semplicemente il contesto di commutazione stessa

Per esempio, se si dispone di una routine di fare un po 'di lavoro e si esegue un'operazione sai bloccherà per qualche tempo (cioè una richiesta di rete), con un co-routine di è possibile passare immediatamente ad un altro di routine senza il sovraccarico di compreso il sistema di pianificazione in questa decisione -. Sì, è il programmatore deve specificare quando co-routine possono passare

Con un sacco di routine facendo molto piccoli pezzi di lavoro e il passaggio volontario tra l'altro, hai raggiunto un livello di efficienza senza scheduler potrebbe mai sperare di raggiungere. È ora possibile avere migliaia di coroutine che lavorano insieme in contrapposizione a decine di fili.

A causa vostra routine ora passare tra di loro un predeterminati punti è ora possibile anche evitare il blocco su strutture dati condivise (perché si sarebbe mai dire il codice per passare ad un altro coroutine nel mezzo di una sezione critica)

Un altro vantaggio è l'utilizzo della memoria molto più basso. Con il modello filettato, ogni thread deve allocare il proprio stack, e quindi l'uso della memoria cresce linearmente con il numero di fili che avete. Con co-routine, il numero di routine si dispone non ha un rapporto diretto con l'utilizzo della memoria.

E, infine, coroutine stanno ricevendo un sacco di attenzione perché in alcuni linguaggi di programmazione (come Python) il tuo discussioni non può funzionare in parallelo in ogni caso - corrono in concomitanza proprio come coroutine, ma senza la poca memoria e programmazione testa libera.

In una parola: prelazione. Coroutine comportano come giocolieri che mantengono consegnare a mano l'un l'altro alcuni punti ben provato. Fili (veri fili) può essere interrotto in qualsiasi punto e poi ripresi in seguito. Naturalmente, questo porta con sé ogni sorta di problemi di conflitto di risorsa, quindi GIL infame di Python -. Globale Interpreter Lock

Molte implementazioni dei thread sono in realtà più simile coroutine.

E 'dipende dalla lingua che si sta utilizzando. Ad esempio in Lua sono la stessa cosa (il tipo di variabile di un coroutine è chiamato thread ).

Di solito, però coroutine implementare volontaria cedendo in cui (si) il programmatore a decidere dove yield, vale a dire, dare il controllo ad un altro di routine.

Le discussioni invece sono gestite automaticamente (arrestato e avviato) dal sistema operativo, e possono anche funzionare contemporaneamente su CPU multicore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top