Asincrono vs Multithreading: c'è differenza?


133

Una chiamata asincrona crea sempre un nuovo thread? Qual è la differenza tra i due?

Una chiamata asincrona crea o utilizza sempre un nuovo thread?

Wikipedia dice :

Nella programmazione informatica, gli eventi asincroni sono quelli che si verificano indipendentemente dal flusso del programma principale. Le azioni asincrone sono azioni eseguite in uno schema non bloccante, che consente al flusso del programma principale di continuare l'elaborazione.

So che le chiamate asincrone possono essere fatte su thread singoli? Com'è possibile?



1
JavaScript non ha thread, ma ha chiamate di metodo asincrone.
Ajedi32,

1
Qualsiasi sistema in cui un processo gestisce più sottoprocessi, il processo di controllo può fornire operazioni asincrone dei sottoprocessi. Nel caso di JavaScript, il browser fornisce il flusso di calcolo. Quando una funzione effettua una chiamata asincrona, il browser può memorizzare il contesto per quella funzione. Ora quello stesso singolo thread del browser può cambiare contesto per riprendere l'esecuzione di un'altra funzione. Mentre nei tradizionali programmi multi-thread, un thread esegue un blocco funzione per consentire a un altro thread di eseguire una funzione diversa. Ogni thread svolge la propria funzione in modo sincrono.
Mike,

Risposte:


82

Questa domanda è quasi troppo generica per rispondere.

Nel caso generale, una chiamata asincrona non crea necessariamente un nuovo thread. Questo è un modo per implementarlo, con un pool di thread preesistente o un processo esterno in altri modi. Dipende fortemente dal linguaggio, dal modello di oggetti (se presente) e dall'ambiente di runtime.

Asincrono significa solo che il thread chiamante non si siede e attende la risposta, né l'attività asincrona si verifica nel thread chiamante.

Oltre a ciò, dovrai diventare più specifico.


7
Quindi, in sostanza, ho ragione nel dire: Multi-threading == Utilizzo di più thread per fornire vantaggi di elaborazione su attività intensive del processore che sono [idealmente] in grado di beneficiare di più processori, nonché vantaggi in situazioni asincrone. Asynchrony == un processo che fa la sua cosa, mentre lo stato che ha chiamato il processo non deve attendere il completamento. (Potrebbe non utilizzare necessariamente più thread per fare ciò, cioè altri componenti hardware potrebbero assumersi la responsabilità).
Evan Sevy,

6
@Michael - Potresti spiegare come può avvenire la programmazione asincrona in un singolo thread con un esempio?
Kumar Vaibhav,

7
@KumarVaibhav: l'esempio più comune è quando un singolo thread funziona su elementi di una coda (ad esempio, la coda dei messaggi di Windows). Se il programma ha l'abitudine di inviare elementi nella propria coda (un modello comune), il bit di codice che invia l'elemento non attende il completamento dell'operazione, ma piuttosto ritorna. L'operazione verrà curata a tempo debito dal circuito principale.
Michael Kohne,

3
Ci può essere una differenza tra il modo in cui il codice viene scritto e il modo in cui viene eseguito. Ad esempio, in C #, posso avere un metodo che avvia un'attività asincrona, il mio metodo è completamente asincrono e può fare altre cose senza attendere il completamento dell'attività. Tuttavia, il CLR può anche decidere di incorporare il mio compito ed eseguirlo in modo sincrono.
Mike,

quale thread esegue l'attività attesa? il metodo contrassegnato con a-sync viene eseguito in modo sincrono fino a raggiungere la parola chiave wait, a questo punto quale thread esegue questa attività in attesa?

102

Ogni volta che l'operazione che deve avvenire in modo asincrono non richiede che la CPU funzioni, tale operazione può essere eseguita senza generare un altro thread. Ad esempio, se l'operazione asincrona è I / O, la CPU non deve attendere il completamento dell'I / O. Deve solo avviare l'operazione e può quindi passare ad altri lavori mentre l'hardware I / O (controller del disco, interfaccia di rete, ecc.) Fa gli I / O. L'hardware comunica alla CPU quando è terminata interrompendo la CPU e il sistema operativo invia l'evento alla tua applicazione.

Astrazioni e API di livello spesso superiore non espongono le API asincrone sottostanti disponibili dal sistema operativo e dall'hardware sottostante. In questi casi, in genere è più semplice creare thread per eseguire operazioni asincrone, anche se il thread generato è in attesa di un'operazione di I / O.

Se l'operazione asincrona richiede che la CPU funzioni, in genere tale operazione deve avvenire in un altro thread affinché sia ​​veramente asincrona. Anche allora, sarà davvero asincrono solo se c'è più di un'unità di esecuzione.


1
Ben spiegato, grazie; ma ho una domanda qui. Hai detto che "Ad esempio, se l'operazione asincrona è I / O, la CPU non deve attendere il completamento dell'I / O. Deve solo avviare l'operazione". La mia domanda è quando il programma è a thread singolo e, nella riga di codice 3, si chiama un'operazione I / O, quindi come è possibile avviare l'operazione nella riga 3 ed eseguire la riga 4 senza attendere il completamento dell'operazione I / O ? Per me, devo inserire il codice nella riga 3 in un nuovo thread per ottenere la riga 4 da eseguire senza attendere il completamento dell'operazione I / O. [Prospettiva pgm Java]
spiderman

1
il motivo è che, sebbene la CPU non debba attendere, la CPU attenderà il completamento dell'operazione di I / O ... Credo che il tuo secondo paragrafo sia la risposta alla mia domanda. In tal caso, devo concludere che in Java, le chiamate asincrone devono essere eseguite in un thread diverso. Per favore, correggimi se sbaglio o fammi sapere se devo pubblicare un nuovo SO qn
spiderman

@spiderman Alcune lingue, come Node.js, hanno un modello di programmazione asincrono. Il linguaggio e il runtime forniscono built-in che consentono l'esecuzione della linea 4 nello stesso thread, anche prima del completamento dell'operazione IO. Ciò è ottenuto dalla linea 3 che fornisce un callback che il runtime invocherà al termine dell'IO.
jrahhali,

@spiderman forse ... la funzione Async del sistema operativo restituisce semplicemente false o qualcosa del genere.
Ciao Yoon,

18

No, le chiamate asincrone non coinvolgono sempre i thread.

In genere iniziano una sorta di operazione che continua in parallelo con il chiamante. Ma quell'operazione potrebbe essere gestita da un altro processo, dal sistema operativo, da altro hardware (come un controller del disco), da qualche altro computer sulla rete o da un essere umano. Le discussioni non sono l'unico modo per fare le cose in parallelo.


12

JavaScript è a thread singolo e asincrono. Quando si utilizza XmlHttpRequest, ad esempio, viene fornita una funzione di callback che verrà eseguita in modo asincrono al ritorno della risposta.

John Resig ha una buona spiegazione del problema relativo al funzionamento dei timer in JavaScript .


12

Il multi threading si riferisce a più di un'operazione che si verifica nello stesso processo. Mentre la programmazione asincrona si diffonde attraverso i processi. Ad esempio, se le mie operazioni chiamano un servizio Web, il thread non deve attendere il ritorno del servizio Web. Qui usiamo la programmazione asincrona che consente al thread di non attendere il completamento di un processo in un'altra macchina. E quando inizia a ricevere risposta dal servizio web può interrompere il thread principale per dire che il servizio web ha completato l'elaborazione della richiesta. Ora il thread principale può elaborare il risultato.


Non sarei in disaccordo un po '. Ho scritto un singolo server HTTP con thread che gestiva più richieste simultanee utilizzando il completamento IO asincrono. Async non richiede che le cose accadano in più percorsi di esecuzione, significa solo che più flussi di calcolo possono sovrapporsi. Un altro modo di vederlo è che su un singolo sistema operativo thread, posso avere 2 processi in esecuzione "contemporaneamente". Dal punto di vista di ciascun processo, vengono eseguiti in modo sincrono. Tuttavia, dal punto di vista del sistema operativo, funziona in modo asincrono.
Mike

11

Windows ha sempre avuto un'elaborazione asincrona fin dai tempi non preventivi (versioni 2.13, 3.0, 3.1, ecc.) Utilizzando il ciclo di messaggi, molto prima di supportare i thread reali. Quindi, per rispondere alla tua domanda, no, non è necessario creare un thread per eseguire l'elaborazione asincrona.


@dmckee - è interessante come i diversi sistemi si evolvono in modi simili.
Otávio Décio,

8

Non è nemmeno necessario che le chiamate asincrone si verifichino sullo stesso sistema / dispositivo di quello che ha richiamato la chiamata. Quindi, se la domanda è: una chiamata asincrona richiede un thread nel processo corrente, la risposta è no. Tuttavia, ci deve essere un thread di esecuzione da qualche parte che elabora la richiesta asincrona.

Il filo conduttore è un termine vago. In sistemi di tasking cooperativi come i primi sistemi operativi Macintosh e Windows, il thread di esecuzione potrebbe essere semplicemente lo stesso processo che ha reso la richiesta in esecuzione un altro stack, puntatore di istruzioni, ecc ... Tuttavia, quando le persone generalmente parlano di chiamate asincrone , in genere significano chiamate gestite da un altro thread se è all'interno del processo (cioè all'interno dello stesso processo) o da un altro processo se è tra processi.

Si noti che la comunicazione tra processi (o tra processi) (IPC) è generalmente generalizzata per includere la comunicazione tra processi, poiché le tecniche di blocco e sincronizzazione dei dati sono generalmente le stesse indipendentemente dal processo in cui vengono eseguiti i thread separati di esecuzione.


7

Alcuni sistemi consentono di sfruttare la concorrenza nel kernel per alcune strutture utilizzando callback. Per un'istanza piuttosto oscura, i callback IO asincroni sono stati usati per implementare i server Internet non bloccanti nei giorni di multitasking non preventivi di Mac System 6-8.

In questo modo hai flussi di esecuzione simultanei "in" programmi senza thread come tali .


5

Asincrono significa solo che non blocchi il tuo programma in attesa che qualcosa (chiamata di funzione, dispositivo, ecc.) Finisca. Può essere implementato in un thread separato, ma è anche comune utilizzare un thread dedicato per attività sincrone e comunicare tramite un qualche tipo di sistema di eventi e quindi ottenere un comportamento simile a quello asincrono.

Esistono esempi di programmi asincroni a thread singolo. Qualcosa di simile a:

...do something
...send some async request
while (not done)
    ...do something else
    ...do async check for results

2

La natura delle chiamate asincrone è tale che, se si desidera che l'applicazione continui a essere in esecuzione mentre la chiamata è in corso, sarà necessario generare un nuovo thread o utilizzare almeno un altro thread creato esclusivamente ai fini di gestione di callback asincroni.

A volte, a seconda della situazione, potresti voler invocare un metodo asincrono, ma far sembrare all'utente sincrono (cioè bloccare fino a quando il metodo asincrono ha segnalato che è completo). Ciò può essere ottenuto tramite API Win32 come WaitForSingleObject .


Questo è vero su alcuni sistemi, ma non su tutti. Unix non richiede di generare o utilizzare un altro thread, a meno che non si chiami il kernel un altro thread, che suppongo sia un modo per vederlo.
Craig S

Questo non è vero neanche su Windows. L'I / O sovrapposto, ad esempio, è asincrono.
Jason Orendorff,
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.