Sync/Async-Programmierung
Wenn ein Anrufer eine Nachricht an einen Empfänger sendet und auf eine Antwort wartet, kann er noch etwas tun? Ich sage Anrufer/Empfänger statt Server/Client, da diese Anrufe überall stattfinden. Als wir zum ersten Mal Computer entwickelten, war alles synchron. Dies kann als Sinuswelle angesehen werden, bei der ein Anrufer und ein Server synchron oder im gleichen Rhythmus sind. Asynchron bedeutet, dass sie nicht synchron sind.
Synchrone I/O
Der Aufrufer sendet die Anfrage an den Empfänger und blockiert sie dann. Dies ist der Fall, wenn der Anrufer blockiert ist, nichts tut und daher eine totale Zeitverschwendung ist. Früher hat die CPU den Prozess vom Prozessor entfernt, weil sie dachte, er sei nur blockiert, und einen neuen Prozess hinzugefügt, der nicht blockiert ist (Kontextwechsel). Der Aufrufer kann also in der Zwischenzeit nicht ausführen. Wenn der Empfänger schließlich antwortet, kann das Betriebssystem den Prozess an den Prozessor zurückgeben. Daher entsperrt der Anrufer. Dies zeigt, wie der Client und der Server vollständig synchron sind.
Beispiel für OS Synchronous I/O:
1. Das Programm fordert die CPU auf, eine Datei von der Festplatte zu lesen.
2. Der Hauptthread des Programms wird von der CPU genommen.
3. Der Lesevorgang wird abgeschlossen, und das Programm beginnt erneut mit der Ausführung.
// A simple Js example
// Program starts
// Programs uses CPU to execute work.
SampleFunction();
// Program reads from the disk
// Program can't do anything until file loads
readfile("SyncExample.dat")
// Program resumes
Speziell aus Sicht von NodeJs verwendet es epoll unter Linux und im Fall von Windows einen Vervollständigungsstapel. Eine andere Sache, die nodeJs tut, ist, einen neuen Thread zu starten, der blockiert, falls etwas eine Blockierungsoperation erfordert. Standardmäßig hat Nodejs 4 Worker-Threads in der libuv- Bibliothek, die es für E/A-Operationen verwendet, aber es ist konfigurierbar.
Beispiel eines asynchronen OS-Aufrufs (NodeJS)
a) Das Programm startet einen sekundären Thread
b) der sekundäre Thread liest von der Festplatte. Offensichtlich entfernt OS aus dem aktuellen Prozessor
c) das Hauptprogramm läuft und wird ausgeführt.
d) Thread beendet und ruft den Haupt-Thread auf.
// A simple Javascript example
// Program starts
// Programs uses CPU to execute work.
SampleFunction();
// Program reads from the disk
// Program hapilly moves on to the samplefunction2
readfile("SyncExample.dat", onReadFinish(console.log))
//file is not probably read yet
SampleFunction2();
//onReadFinish function called
// executing it
Jetzt werden wir die Dinge rein aus der Sicht eines Clients und Servers (Backend) besprechen.
Synchronizität kann also auch als Client-Eigenschaft bezeichnet werden, wo sie warten oder weitermachen kann. Heutzutage ist kein Client synchron, und die meisten Bibliotheken sind asynchron. Meistens sendet der Client die Anfrage und erhält eine Antwort, und ein Rückruf wird immer dann aufgerufen, wenn die Antwort ausgeführt wird. Speziell in Node.js gibt es also eine Hauptschleife der Ereignisschleife, die nach der Antwort sucht.
Das kann verwirrend sein, da es für mich immer so war, wenn jemand es mit diesem schönen Beispiel aus dem wirklichen Leben erklärte, dass Synchron so ist, als würde man in einem Meeting eine Frage stellen, wo das Meeting weitergeht, wenn der Moderator antwortet. Asynchron ist wie das Stellen einer Frage in einer E-Mail, die beantwortet werden kann, wann immer der Empfänger Zeit hat.
Asynchrone Backend-Verarbeitung
Als Backend-Ingenieur wäre es unfair, wenn ich nicht darüber spreche, das Backend asynchron zu machen. In vielen Code-/Repositories ist der Client hauptsächlich asynchron, aber das Backend lässt ihn immer noch warten. Wenn also ein Client anfordert, einige Daten zu pushen, sagen wir, um einen Datenbankaufruf durchzuführen, wird er oft gebeten, auf die Antwort vom Backend zu warten, das nach dem Commit eine Antwort mit dem Status 200 zurückgibt. Wenn wir nun die Linse zum Backend bewegen, ist das Frontend asynchron, aber das Backend ist immer noch synchron. Wie geben wir also eine sofortige Antwort zurück?
Eine der Lösungen besteht darin, diese schöne Datenstruktur namens Warteschlange zu verwenden. Wenn ein Client eine Anfrage sendet, versprechen wir nicht, sie sofort auszuführen, aber wir spülen sie in die Warteschlange. Der Grund dafür ist, dass das Backend möglicherweise die vorherigen Anfragen abschließt und der Client nicht mehr blockiert ist. Wir können die Antwort senden, dass wir die Anfrage in die Warteschlange gestellt haben, und hier ist eine Zusage/JobID. Weitere Informationen finden Sie unter Nachrichtenwarteschlangen .
Davon abgesehen gibt es je nach Anwendungsfall sehr beliebte Lösungen.
Ein reales Beispiel für eine asynchrone Workload:
a) Asynchrone Commits in Postgres ↗ .
b) Asynchrones I/O unter Linux (io-uring).
c) Asynchronous I/O fsync (fs-cache): Jedes Mal, wenn wir etwas in eine Datei schreiben, wird es nicht direkt auf die Festplatte geschrieben, sondern in den Dateisystem-Cache. Es gibt einen Cache im Betriebssystem, und die Schreibvorgänge gehen in Seiten. Und dann löscht das Betriebssystem alle Seiten auf einmal.
Wir können das Ganze wie folgt zusammenfassen:
a) Der synchrone Programmieransatz führt Aufgaben sequentiell aus. Jede Aufgabe wird ausgeführt, nachdem sie auf die Beendigung einer vorhergehenden Aufgabe gewartet hat.
b) Wenn eine Aufgabe in einem asynchronen Programmiermodell ausgeführt wird, können wir zu einer anderen übergehen, ohne auf die Beendigung der vorherigen zu warten.
Danke fürs Lesen; Ich hoffe, es war hilfreich.
Bei weiteren Zweifeln können Sie sich gerne über LinkedIn / Instagram verbinden .

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































