Asynchrones vs Multithreading - Gibt es einen Unterschied?

133

Erstellt ein asynchroner Aufruf immer einen neuen Thread? Was ist der Unterschied zwischen den beiden?

Erstellt oder verwendet ein asynchroner Aufruf immer einen neuen Thread?

Wikipedia sagt :

Bei der Computerprogrammierung sind asynchrone Ereignisse solche, die unabhängig vom Hauptprogrammablauf auftreten. Asynchrone Aktionen sind Aktionen, die in einem nicht blockierenden Schema ausgeführt werden, sodass der Hauptprogrammfluss die Verarbeitung fortsetzen kann.

Ich weiß, dass asynchrone Aufrufe für einzelne Threads ausgeführt werden können. Wie ist das möglich?

Ted Smith
quelle
1
JavaScript hat keine Threads, aber asynchrone Methodenaufrufe.
Ajedi32
1
In jedem System, in dem ein Prozess mehrere Unterprozesse verwaltet, kann der Steuerungsprozess einen asynchronen Betrieb der Unterprozesse bereitstellen. Bei JavaScript stellt der Browser den Rechenstrom bereit. Wenn eine Funktion einen asynchronen Aufruf ausführt, kann der Browser den Kontext für diese Funktion speichern. Jetzt kann derselbe einzelne Browser-Thread den Kontext ändern, um die Ausführung einer anderen Funktion fortzusetzen. Während in herkömmlichen Multithread-Programmen ein Thread einen Funktionsblock ausführt, damit ein anderer Thread eine andere Funktion ausführen kann. Jeder Thread führt synchron seine eigene Funktion aus.
Mike

Antworten:

82

Diese Frage ist fast zu allgemein, um sie zu beantworten.

Im allgemeinen Fall erstellt ein asynchroner Aufruf nicht unbedingt einen neuen Thread. Dies ist eine Möglichkeit, dies zu implementieren, wobei ein bereits vorhandener Thread-Pool oder ein externer Prozess andere Möglichkeiten darstellen. Dies hängt stark von der Sprache, dem Objektmodell (falls vorhanden) und der Laufzeitumgebung ab.

Asynchron bedeutet nur, dass der aufrufende Thread nicht auf die Antwort wartet und die asynchrone Aktivität auch nicht im aufrufenden Thread stattfindet.

Darüber hinaus müssen Sie spezifischer werden.

Michael Kohne
quelle
7
Grundsätzlich habe ich also Recht, wenn ich sage: Multithreading == Verwenden mehrerer Threads, um Verarbeitungsvorteile bei prozessorintensiven Aufgaben zu erzielen, die [idealerweise] von mehreren Prozessoren profitieren können, sowie Vorteile in asynchronen Situationen. Asynchronität == Ein Prozess, der seine Aufgabe erfüllt, während der Status, der den Prozess aufgerufen hat, nicht auf den Abschluss warten muss. (Möglicherweise werden hierfür nicht unbedingt mehrere Threads verwendet, dh andere Hardwarekomponenten übernehmen möglicherweise die Verantwortung.)
Evan Sevy
6
@Michael - Könnten Sie bitte anhand eines Beispiels erklären, wie asynchrone Programmierung in einem einzelnen Thread erfolgen kann?
Kumar Vaibhav
7
@KumarVaibhav - Das häufigste Beispiel ist, wenn ein einzelner Thread Elemente aus einer Warteschlange (z. B. der Windows-Nachrichtenwarteschlange) bearbeitet. Wenn das Programm die Gewohnheit hat, Elemente in seine eigene Warteschlange zu senden (ein allgemeines Muster), wartet das Codebit, das das Element sendet, nicht auf den Abschluss des Vorgangs, sondern kehrt einfach zurück. Die Operation wird zu gegebener Zeit von der Hauptschleife erledigt.
Michael Kohne
3
Es kann einen Unterschied geben, wie Code geschrieben und wie er ausgeführt wird. In C # kann ich beispielsweise eine Methode haben, die eine asynchrone Aufgabe startet, meine Methode ist vollständig asynchron und kann andere Dinge tun, ohne auf den Abschluss der Aufgabe zu warten. Die CLR kann jedoch auch entscheiden, meine Aufgabe zu integrieren und synchron auszuführen.
Mike
Welcher Thread führt die erwartete Aufgabe aus? Die mit a-sync gekennzeichnete Methode wird synchron ausgeführt, bis das Schlüsselwort await erreicht ist. Welcher Thread führt an dieser Stelle diese wartbare Aufgabe aus?
102

Wenn für die asynchrone Operation keine CPU erforderlich ist, kann diese Operation ausgeführt werden, ohne dass ein weiterer Thread erzeugt wird. Wenn die asynchrone Operation beispielsweise E / A ist, muss die CPU nicht warten, bis die E / A abgeschlossen ist. Es muss nur den Vorgang starten und kann dann mit anderen Arbeiten fortfahren, während die E / A-Hardware (Festplattencontroller, Netzwerkschnittstelle usw.) die E / A-Arbeit erledigt. Die Hardware teilt der CPU mit, wann sie fertig ist, indem sie die CPU unterbricht, und das Betriebssystem sendet das Ereignis dann an Ihre Anwendung.

Häufig machen übergeordnete Abstraktionen und APIs die zugrunde liegenden asynchronen APIs, die vom Betriebssystem und der zugrunde liegenden Hardware verfügbar sind, nicht verfügbar. In diesen Fällen ist es normalerweise einfacher, Threads für asynchrone Vorgänge zu erstellen, selbst wenn der erzeugte Thread nur auf einen E / A-Vorgang wartet.

Wenn für die asynchrone Operation die CPU arbeiten muss, muss diese Operation im Allgemeinen in einem anderen Thread ausgeführt werden, damit sie wirklich asynchron ist. Selbst dann ist es wirklich nur asynchron, wenn es mehr als eine Ausführungseinheit gibt.

Karunski
quelle
1
Gut erklärt, danke; aber ich habe hier eine frage. Sie haben Folgendes erwähnt: "Wenn die asynchrone Operation beispielsweise E / A ist, muss die CPU nicht auf den Abschluss der E / A warten. Sie muss lediglich die Operation starten." Meine Frage ist, wenn das Programm Single-Threaded ist und Sie in Codezeile 3 sagen, dass Sie eine E / A-Operation aufrufen. Wie können Sie dann die Operation in Zeile 3 starten und die Zeile 4 ausführen, ohne auf den Abschluss der E / A-Operation zu warten? ? Für mich muss ich den Code in Zeile 3 in einen neuen Thread einfügen, damit die Zeile 4 ausgeführt werden kann, ohne auf den Abschluss der E / A-Operation zu warten. [Java pgm-Perspektive]
Spiderman
1
Der Grund dafür ist, dass die CPU zwar nicht warten muss, die CPU jedoch auf den Abschluss des E / A-Vorgangs wartet ... Ich glaube, Ihr zweiter Absatz ist die Antwort auf meine Anfrage. In einem solchen Fall muss ich zu dem Schluss kommen, dass in Java asynchrone Aufrufe in einem anderen Thread ausgeführt werden müssen. Bitte korrigieren Sie mich, wenn ich falsch liege oder lassen Sie mich wissen, wenn ich einen neuen SO qn
Spiderman
@spiderman Einige Sprachen, wie Node.js, haben ein asynchrones Programmiermodell. Die Sprache und die Laufzeit bieten integrierte Funktionen, mit denen Zeile 4 im selben Thread ausgeführt werden kann, noch bevor der E / A-Vorgang abgeschlossen ist. Dies wird erreicht, indem Zeile 3 einen Rückruf bereitstellt, den die Laufzeit nach Beendigung der E / A aufruft.
Jrahhali
@spiderman vielleicht ... die Async-Funktion des Betriebssystems gibt einfach false oder etwas direkt zurück.
Byeongin Yoon
18

Nein, asynchrone Aufrufe beinhalten nicht immer Threads.

Sie starten normalerweise eine Operation, die parallel zum Anrufer fortgesetzt wird. Diese Operation kann jedoch von einem anderen Prozess, vom Betriebssystem, von anderer Hardware (wie einem Festplattencontroller), von einem anderen Computer im Netzwerk oder von einem Menschen ausgeführt werden. Threads sind nicht die einzige Möglichkeit, Dinge parallel zu erledigen.

Jason Orendorff
quelle
12

JavaScript ist Single-Threaded und asynchron. Wenn Sie beispielsweise XmlHttpRequest verwenden, stellen Sie ihm eine Rückruffunktion zur Verfügung, die asynchron ausgeführt wird, wenn die Antwort zurückgegeben wird.

John Resig hat eine gute Erklärung für die damit verbundene Frage, wie Timer in JavaScript funktionieren .

George V. Reilly
quelle
12

Multithreading bezieht sich auf mehr als eine Operation, die im selben Prozess ausgeführt wird. Während sich die asynchrone Programmierung über Prozesse erstreckt. Wenn meine Operationen beispielsweise einen Webdienst aufrufen, muss der Thread nicht warten, bis der Webdienst zurückkehrt. Hier verwenden wir die asynchrone Programmierung, mit der der Thread nicht auf den Abschluss eines Prozesses auf einem anderen Computer warten kann. Wenn eine Antwort vom Webservice angezeigt wird, kann der Hauptthread unterbrochen werden, um anzuzeigen, dass der Webdienst die Verarbeitung der Anforderung abgeschlossen hat. Jetzt kann der Haupt-Thread das Ergebnis verarbeiten.

Murugan Gopalan
quelle
Ich würde ein bisschen nicht zustimmen. Ich habe einen HTTP-Server mit einem Thread geschrieben, der mehrere gleichzeitige Anforderungen mithilfe der asynchronen E / A-Vervollständigung verarbeitet. Async erfordert nicht, dass Dinge in mehreren Ausführungspfaden geschehen, sondern bedeutet nur, dass sich mehrere Rechenströme überlappen können. Eine andere Sichtweise ist, dass auf einem Betriebssystem mit einem Thread zwei Prozesse "gleichzeitig" ausgeführt werden können. Aus Sicht jedes Prozesses laufen sie synchron. Aus Sicht des Betriebssystems arbeitet es jedoch asynchron.
Mike
11

Windows hatte seit den nicht präemptiven Zeiten (Versionen 2.13, 3.0, 3.1 usw.) immer eine asynchrone Verarbeitung unter Verwendung der Nachrichtenschleife, lange bevor echte Threads unterstützt wurden. Um Ihre Frage zu beantworten, nein, es ist nicht erforderlich, einen Thread zu erstellen, um eine asynchrone Verarbeitung durchzuführen.

Otávio Décio
quelle
@dmckee - es ist interessant, wie sich verschiedene Systeme auf ähnliche Weise entwickeln.
Otávio Décio
8

Asynchrone Anrufe müssen nicht einmal auf demselben System / Gerät erfolgen wie derjenige, der den Anruf aufruft. Wenn die Frage lautet: Benötigt ein asynchroner Aufruf im aktuellen Prozess einen Thread, lautet die Antwort Nein. Es muss jedoch irgendwo ein Ausführungsthread vorhanden sein, der die asynchrone Anforderung verarbeitet.

Thread of Execution ist ein vager Begriff. In kooperativen Tasking-Systemen wie den frühen Macintosh- und Windows-Betriebssystemen kann der Ausführungsthread einfach derselbe Prozess sein, bei dem die Anforderung einen anderen Stapel, einen Befehlszeiger usw. ausführt. Wenn jedoch allgemein von asynchronen Aufrufen gesprochen wird Dies sind normalerweise Aufrufe, die von einem anderen Thread verarbeitet werden, wenn es sich um einen Prozess handelt (dh innerhalb desselben Prozesses), oder von einem anderen Prozess, wenn es sich um einen Interprozess handelt.

Beachten Sie, dass die Interprozess- (oder Interprozess-) Kommunikation (IPC) üblicherweise so verallgemeinert wird, dass sie die prozessinterne Kommunikation einschließt, da die Techniken zum Sperren und Synchronisieren von Daten normalerweise gleich sind, unabhängig davon, in welchem ​​Prozess die einzelnen Ausführungsthreads ausgeführt werden.

Mike
quelle
7

Bei einigen Systemen können Sie die Parallelität im Kernel für einige Einrichtungen mithilfe von Rückrufen nutzen. In einem eher undurchsichtigen Fall wurden asynchrone E / A-Rückrufe verwendet, um nicht blockierende Internet-Server in den nicht präemptiven Multitasking-Tagen von Mac System 6-8 zu implementieren.

Auf diese Weise haben Sie gleichzeitige Ausführungsströme "in" Ihrem Programm ohne Threads als solche .

dmckee --- Ex-Moderator Kätzchen
quelle
5

Asynchron bedeutet nur, dass Sie Ihr Programm nicht blockieren, während Sie darauf warten, dass etwas (Funktionsaufruf, Gerät usw.) beendet wird. Es kann in einem separaten Thread implementiert werden, es ist jedoch auch üblich, einen dedizierten Thread für synchrone Aufgaben zu verwenden und über eine Art Ereignissystem zu kommunizieren, um so ein asynchrones Verhalten zu erzielen.

Es gibt Beispiele für asynchrone Single-Thread-Programme. Etwas wie:

...do something
...send some async request
while (not done)
    ...do something else
    ...do async check for results
Milan Babuškov
quelle
2

Die Art der asynchronen Aufrufen ist so , dass, wenn Sie die Anwendung wollen weiter ausgeführt werden , während der Anruf im Gange ist, werden Sie entweder brauchen Laichen einen neuen Thread oder zumindest verwenden einen anderen Thread, dass Sie für die Zwecke der allein geschaffen haben Behandlung von asynchronen Rückrufen.

Abhängig von der Situation möchten Sie manchmal eine asynchrone Methode aufrufen, sie dem Benutzer jedoch als synchron erscheinen lassen (dh blockieren, bis die asynchrone Methode signalisiert hat, dass sie abgeschlossen ist). Dies kann durch Win32-APIs wie WaitForSingleObject erreicht werden .

LeopardSkinPillBoxHat
quelle
Dies gilt für einige Systeme, jedoch nicht für alle. Unter Unix müssen Sie keinen anderen Thread erzeugen oder verwenden, es sei denn, Sie nennen den Kernel einen anderen Thread. Ich nehme an, dies ist eine Möglichkeit, ihn zu betrachten.
Craig S
Dies gilt auch unter Windows nicht. Überlappende E / A sind beispielsweise asynchron.
Jason Orendorff