asynchron vs nicht blockierend


373

Was ist der Unterschied zwischen asynchronen und nicht blockierenden Anrufen? Auch zwischen blockierenden und synchronen Anrufen (mit Beispielen bitte)?



1
Ich habe ein gutes Verständnis für die Unterschiede bekommen, als ich das Buch <Unix Networking Programming> Spalte 1, Kapitel 6 gelesen habe.
Bin

2
Eine interessante Artikel: Boost - Anwendungsleistung mit asynchronem I / O . Es kategorisiert E / A-Paradigmen in 4 Kategorien: (1) Blockieren + Synchron, (2) Nicht Blockieren + Synchron, (3) Blockieren + Asynchron und (4) Nicht Blockieren + Asynchron.
MS Dousti

@MSDousti Von einem Google-Experten wurde mir gesagt, dass dies in gewisser Weise falsch ist.
Rick

@MSDousti Nach einigen Studien denke ich, dass es keine Verbindung (3) und (2) gibt, wie Sie in den Kommentaren beschreiben. Überprüfen Sie die Definition von Asynchronous. Es handelt sich um das Gleiche wie Non-Blocking. Wie Sie in der Top-Antwort sehen können, bestätigt dies meine Meinung. Abruf- und Rückruffunktion sind lediglich Möglichkeiten / Muster zur Implementierung von Asynchron. Ja, ich sage, dass Blockieren, Synchron und Nicht-Blockieren, Asynchron sind zwei Synonympaare.
Rick

Antworten:


304

In vielen Fällen sind sie unterschiedliche Namen für dieselbe Sache, aber in einigen Kontexten sind sie sehr unterschiedlich. Es kommt also darauf an. Die Terminologie wird in der gesamten Softwareindustrie nicht vollständig konsistent angewendet.

In der klassischen Sockets-API wird beispielsweise ein nicht blockierender Socket einfach sofort mit einer speziellen Fehlermeldung "würde blockieren" zurückgegeben, während ein blockierender Socket blockiert hätte. Sie müssen eine separate Funktion verwenden, z. B. selectoder pollum herauszufinden, wann ein guter Zeitpunkt für einen erneuten Versuch ist.

Asynchrone Sockets (wie von Windows-Sockets unterstützt) oder das in .NET verwendete asynchrone E / A-Muster sind jedoch praktischer. Sie rufen eine Methode auf, um eine Operation zu starten, und das Framework ruft Sie zurück, wenn dies abgeschlossen ist. Auch hier gibt es grundlegende Unterschiede. Asynchrone Win32-Sockets "marshallen" ihre Ergebnisse auf einem bestimmten GUI-Thread, indem sie Windows-Nachrichten übergeben, während asynchrone .NET-E / A-Vorgänge mit freiem Thread ausgeführt werden (Sie wissen nicht, auf welchem ​​Thread Ihr Rückruf aufgerufen wird).

Sie bedeuten also nicht immer dasselbe. Um das Socket-Beispiel zu destillieren, könnten wir sagen:

  • Blockieren und Synchronisieren bedeuten dasselbe: Sie rufen die API auf, sie legt den Thread auf, bis sie eine Antwort hat, und gibt sie an Sie zurück.
  • Nicht blockierend bedeutet, dass wenn eine Antwort nicht schnell zurückgegeben werden kann, die API sofort mit einem Fehler zurückkehrt und nichts anderes tut. Es muss also eine verwandte Methode geben, um abzufragen, ob die API zum Aufrufen bereit ist (dh um eine Wartezeit auf effiziente Weise zu simulieren und manuelle Abfragen in einer engen Schleife zu vermeiden).
  • Asynchron bedeutet, dass die API immer sofort zurückkehrt, nachdem eine "Hintergrund" -Anstrengung gestartet wurde, um Ihre Anforderung zu erfüllen. Daher muss es einen verwandten Weg geben, um das Ergebnis zu erhalten.

Bereitschaftszustand E / A statt Abschlusszustand E / A; unter Linux siehe libaio
Will

4
Vielen Dank für den Hinweis, dass die Begriffe kontextsensitiv sind und manchmal inkonsistent verwendet werden. Ich finde vor allem in der Technologie, aber auch in anderen Bereichen, dass es oft nützlicher ist, diese Tatsache anzuerkennen, als in Debatten darüber zu geraten, welche genaue Definition richtig ist, wie es manchmal vorkommt.
Chad NB

2
Follow-up F: Die Antwort scheint zwei verschiedene Unterschiede zwischen den Begriffen zu machen. Erstens bedeutet die Benachrichtigung: Nicht blockierend, dass die Anwendung später erneut prüfen muss (Abfrage), während Async impliziert, dass wir dies vergessen und uns auf das Framework / Betriebssystem verlassen können, um uns per Rückruf oder Veröffentlichung eines Ereignisses zu benachrichtigen. Zweitens macht die Aktion: Nicht blockieren absolut nichts anderes als einen Fehler zurückzugeben, während asynchron die Aktion in die Warteschlange stellt oder sie in gewissem Sinne "im Hintergrund" ausführt. Welcher Unterschied ist für die Unterscheidung der Begriffe wichtiger? Ist eine der beiden Unterscheidungen stärker mit einem Begriff verbunden? Oder ist es mehrdeutig?
Chad NB

2
@ChadNB - Nicht-Blockieren ist stark mit Abfragen verbunden. In Bezug auf die Frage, ob sich die API an Ihren Aufrufversuch "erinnert": Der einzige Grund, an den sich die API erinnert, besteht darin, Sie zurückzurufen. Wenn Sie es zum erneuten Abrufen aufrufen möchten, müssen Sie bereits den erforderlichen Status beibehalten, um diesen nachfolgenden Aufruf ausführen zu können, sodass die API keinen Wert hinzufügen würde, indem sie auch den Status beibehält.
Daniel Earwicker

6
Anstatt zu sagen, dass der nicht blockierende Anruf einen "Fehler" zurückgibt, wäre es meiner Meinung nach genauer zu sagen, dass ein nicht blockierender Anruf so viel tut, wie im Wesentlichen sofort erledigt werden kann, und dann angibt, wie viel er getan hat. Bei einigen Vorgängen beträgt der Arbeitsaufwand entweder "alles" oder "nichts", bei einigen anderen Vorgängen (z. B. Stream-E / A) wird möglicherweise eine quantitative Angabe zurückgegeben. Das Nicht-Blockieren entspricht semantisch dem Blockieren mit einem sehr kurzen Zeitlimit, wenn die Blockierungs-E / A-Implementierung ermöglicht, dass eine Operation, deren Zeitüberschreitung abgelaufen ist, später problemlos wiederholt wird (einige tun dies, andere nicht).
Supercat

56

synchron / asynchron soll die Beziehung zwischen zwei Modulen beschreiben.
Blockieren / Nichtblockieren beschreibt die Situation eines Moduls.

Ein Beispiel:
Modul X: "I".
Modul Y: "Buchhandlung".
X fragt Y: Haben Sie ein Buch mit dem Namen "c ++ primer"?

1) Blockieren: Bevor Y auf X antwortet, wartet X dort auf die Antwort. Jetzt blockiert X (ein Modul). X und Y sind zwei Threads oder zwei Prozesse oder ein Thread oder ein Prozess? Wir wissen es nicht.

2) nicht blockierend: Bevor Y auf X antwortet, verlässt X es einfach und macht andere Dinge. X kann alle zwei Minuten zurückkommen, um zu überprüfen, ob Y seine Arbeit beendet hat? Oder kommt X nicht zurück, bis Y ihn anruft? Wir wissen es nicht. Wir wissen nur, dass X andere Dinge tun kann, bevor Y seine Arbeit beendet. Hier ist X (ein Modul) nicht blockierend. X und Y sind zwei Threads oder zwei Prozesse oder ein Prozess? Wir wissen es nicht. ABER wir sind sicher, dass X und Y nicht ein Thread sein können.

3) synchron: Bevor Y auf X antwortet, wartet X dort auf die Antwort. Dies bedeutet, dass X nicht fortfahren kann, bis Y seinen Job beendet hat. Jetzt sagen wir: X und Y (zwei Module) sind synchron. X und Y sind zwei Threads oder zwei Prozesse oder ein Thread oder ein Prozess? Wir wissen es nicht.

4) asynchron: Bevor Y auf X antwortet, verlässt X dort und X kann andere Aufgaben erledigen. X wird nicht zurückkommen, bis Y ihn anruft. Jetzt sagen wir: X und Y (zwei Module) sind asynchron. X und Y sind zwei Threads oder zwei Prozesse oder ein Prozess? Wir wissen es nicht. ABER wir sind sicher, dass X und Y nicht ein Thread sein können.


Bitte beachten Sie die beiden obigen fett gedruckten Sätze. Warum enthält der fette Satz in 2) zwei Fälle, während der fette Satz in 4) nur einen Fall enthält? Dies ist ein Schlüssel zum Unterschied zwischen nicht blockierend und asynchron.

Hier ist ein typisches Beispiel für nicht blockierend und synchron:

// thread X
while (true)
{
    msg = recv(Y, NON_BLOCKING_FLAG);
    if (msg is not empty)
    {
        break;
    }
    sleep(2000); // 2 sec
}

// thread Y
// prepare the book for X
send(X, book);

Sie können sehen, dass dieses Design nicht blockiert (Sie können sagen, dass diese Schleife die meiste Zeit etwas Unsinniges tut, aber in den Augen der CPU läuft X, was bedeutet, dass X nicht blockiert), während X und Y synchron sind, weil X dies kann Machen Sie keine weiteren Dinge (X kann nicht aus der Schleife herausspringen), bis das Buch von Y stammt.
Normalerweise ist das Blockieren von X in diesem Fall viel besser, da das Nicht-Blockieren viel Ressourcen für eine dumme Schleife verbraucht. Dieses Beispiel hilft Ihnen jedoch dabei, die Tatsache zu verstehen: Nicht blockieren bedeutet nicht asynchron.

Die vier Wörter machen uns leicht verwirrt. Wir sollten uns daran erinnern, dass die vier Wörter für die Gestaltung der Architektur dienen. Nur wenn Sie lernen, wie man eine gute Architektur entwirft, können Sie sie unterscheiden.

Zum Beispiel können wir eine solche Art von Architektur entwerfen:

// Module X = Module X1 + Module X2
// Module X1
while (true)
{
    msg = recv(many_other_modules, NON_BLOCKING_FLAG);
    if (msg is not null)
    {
        if (msg == "done")
        {
            break;
        }
        // create a thread to process msg
    }
    sleep(2000); // 2 sec
}
// Module X2
broadcast("I got the book from Y");


// Module Y
// prepare the book for X
send(X, book);

Im Beispiel hier können wir das sagen

  • X1 ist nicht blockierend
  • X1 und X2 sind synchron
  • X und Y sind asynchron

Bei Bedarf können Sie auch die in X1 erstellten Threads mit den vier Wörtern beschreiben.

Die wichtigeren Dinge sind: Wann verwenden wir synchron statt asynchron? Wann verwenden wir das Blockieren anstelle des Nicht-Blockierens?

Warum blockiert Nginx nicht? Warum blockiert Apache?

Um eine gute Wahl zu treffen, müssen Sie Ihren Bedarf analysieren und die Leistung verschiedener Architekturen testen. Es gibt keine solche Architektur, die für verschiedene Anforderungen geeignet ist.


7
IMO die beste Antwort, da sie die Essenz des Konzepts erfasst: die Beziehung zwischen einem oder zwei Teilnehmern.
Fábio

In 1 und 3 fungiert Y als BEGRENZTE Ressource. Es gibt keine Y mehr, um X zu helfen
UVM

46
  • Asynchron bezieht sich auf etwas, das parallel ausgeführt wird, beispielsweise auf einen anderen Thread.
  • Das Nicht-Blockieren bezieht sich häufig auf das Abrufen , dh das Überprüfen, ob eine bestimmte Bedingung erfüllt ist (Socket ist lesbar, Gerät verfügt über mehr Daten usw.)

17
Wenn E / A beteiligt ist, ist asynchron normalerweise nicht "parallel" oder "ein anderer Thread", meistens basiert es auf Benachrichtigungen. das heißt: nicht blockieren, nicht abfragen, nur das Signal erhalten. Natürlich kann argumentiert werden, dass das Signal aus der 'realen Welt' kommt, was als 'ein anderer Thread' gedacht werden kann ...
Javier

Nun ja, wir können den ganzen Tag über den genauen Wortlaut streiten :)
Nikolai Fetissov

aber wie erklärt man das AIO unter Linux? die sowohl Async als auch Non-Blocking verwendet. AIO LINKS
Djvu

16
Für jeden, der diese Antwort liest: Hier geht es nicht um genaue Formulierungen. Ebenso wie Parallelität und Parallelität nicht dieselben Begriffe sind und ihre Unterscheidung kein Wortlaut ist. Asynchronität und Parallelität sind zwei verschiedene Tiere, und diese Antwort lässt sie ungenau gleich sein.
Ptival

2
Async bedeutet nicht unbedingt, dass es parallel ausgeführt wird. Weitere Informationen zum gleichzeitigen und parallelen Programmieren finden Sie in diesem großartigen Beitrag zum Stackoverflow.
BARJ

17

Wenn Sie diese Frage in Java 7 in den Kontext von NIO und NIO.2 stellen, ist async IO einen Schritt weiter fortgeschritten als das Nicht-Blockieren. Bei nicht blockierenden Java NIO-Aufrufen würden alle Kanäle (SocketChannel, ServerSocketChannel, FileChannel usw.) durch Aufrufen als solche festgelegt AbstractSelectableChannel.configureBlocking(false). Nach der Rückkehr dieser E / A-Aufrufe müssen Sie jedoch wahrscheinlich noch die Überprüfungen steuern, z. B. ob und wann erneut gelesen / geschrieben werden muss usw.
Zum Beispiel:

while (!isDataEnough()) {
    socketchannel.read(inputBuffer);
    // do something else and then read again
}

Mit der asynchronen API in Java 7 können diese Steuerelemente auf vielseitigere Weise erstellt werden. Eine der beiden Möglichkeiten ist die Verwendung CompletionHandler. Beachten Sie, dass beide readAnrufe nicht blockieren.

asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */, 
    new CompletionHandler<Integer, Object>() {
        public void completed(Integer result, Object attachment) {...}  
        public void failed(Throwable e, Object attachment) {...}
    }
}

3
FileChannelist nicht auswählbar und kann nicht als nicht blockierend konfiguriert werden.
Michaelliu

15

Wie Sie wahrscheinlich an der Vielzahl unterschiedlicher (und sich oft gegenseitig ausschließender) Antworten erkennen können, hängt es davon ab, wen Sie fragen. In einigen Bereichen sind die Begriffe synonym. Oder sie beziehen sich jeweils auf zwei ähnliche Konzepte:

  • Eine Interpretation ist, dass der Aufruf im Hintergrund etwas tut, das im Wesentlichen unbeaufsichtigt ist, damit das Programm nicht durch einen langwierigen Prozess aufgehalten werden kann, den es nicht steuern muss. Das Abspielen von Audio könnte ein Beispiel sein - ein Programm könnte eine Funktion zum Abspielen (sagen wir) eines MP3 aufrufen und von diesem Punkt an mit anderen Dingen fortfahren, während es dem Betriebssystem überlassen bleibt, den Prozess des Renderns des Audios auf der Soundhardware zu verwalten .
  • Die alternative Interpretation ist, dass der Aufruf etwas tut, das das Programm überwachen muss, aber den größten Teil des Prozesses im Hintergrund ablaufen lässt, wobei das Programm nur an kritischen Punkten des Prozesses benachrichtigt wird. Beispielsweise kann die asynchrone Datei-E / A ein Beispiel sein - das Programm stellt dem Betriebssystem einen Puffer zum Schreiben in eine Datei zur Verfügung, und das Betriebssystem benachrichtigt das Programm nur, wenn der Vorgang abgeschlossen ist oder ein Fehler auftritt.

In beiden Fällen soll zugelassen werden, dass das Programm nicht blockiert wird, bis ein langsamer Prozess abgeschlossen ist. Wie das Programm voraussichtlich reagieren wird, ist der einzige wirkliche Unterschied. Welcher Begriff sich auf welchen bezieht, ändert sich auch von Programmierer zu Programmierer, von Sprache zu Sprache oder von Plattform zu Plattform. Oder die Begriffe können sich auf völlig unterschiedliche Konzepte beziehen (z. B. die Verwendung von synchron / asynchron in Bezug auf die Thread-Programmierung).

Entschuldigung, aber ich glaube nicht, dass es eine einzige richtige Antwort gibt, die global wahr ist.


1
+1 Gute Antwort. Die Benutzer müssen sich darüber im Klaren sein, dass "asynchron" entweder nicht blockierend oder den asynchronen Microsoft-Ansatz (ereignisbasiert / Rückruf) bedeuten kann .
Ingenieur

14

Ein nicht blockierender Aufruf wird sofort mit allen verfügbaren Daten zurückgegeben: der vollen Anzahl angeforderter Bytes, weniger oder gar keiner.

Ein asynchroner Anruf fordert eine Übertragung an, die vollständig (vollständig) ausgeführt wird, aber zu einem späteren Zeitpunkt abgeschlossen wird.


Nicht-Blockieren gibt kein Ergebnis nichts zurück
CEO bei Apartico

9

Nicht blockierend: Diese Funktion wartet nicht auf dem Stapel.

Asynchron: Die Arbeit kann im Namen des Funktionsaufrufs fortgesetzt werden, nachdem dieser Aufruf den Stapel verlassen hat


1
@Marenz bedeutet, dass Sie nicht nicht blockierende Io direkt mit Posix-Aufrufen ausführen können. Das ändert nichts an der Bedeutung, die er hier gibt.
tmc

@Marenz Das bedeutet nur, dass das Flag für Dateien ignoriert wird. Dies hat keinen Einfluss auf die Bedeutung dieser Antwort.
Marquis von Lorne

8

Synchron wird als gleichzeitig ablaufend definiert.

Asynchron ist definiert als nicht gleichzeitig.

Dies ist es, was die erste Verwirrung verursacht. Synchron ist eigentlich das, was als parallel bekannt ist. Während Asynchron sequentiell ist, tun Sie dies und dann das.

Das ganze Problem besteht nun darin, ein asynchrones Verhalten zu modellieren, da Sie eine Operation haben, die die Antwort einer anderen benötigt, bevor sie beginnen kann. Es handelt sich also um ein Koordinationsproblem. Woher wissen Sie, dass Sie diese Operation jetzt starten können?

Die einfachste Lösung ist das Blockieren.

Beim Blockieren warten Sie einfach, bis das andere erledigt ist, und erhalten eine Antwort, bevor Sie mit dem Vorgang fortfahren, der dies erfordert.

Wenn Sie also Butter auf Toast legen müssen und daher zuerst die gezüchteten Toastbrotstücke benötigen. Die Art und Weise, wie Sie sie koordinieren würden, besteht darin, dass Sie zuerst das gezüchtete Toaststück anstoßen, dann endlos auf den Toaster starren, bis der Toast platzt, und dann Butter darauf legen.

Es ist die einfachste Lösung und funktioniert sehr gut. Es gibt keinen wirklichen Grund, es nicht zu verwenden, es sei denn, Sie haben zufällig auch andere Dinge zu tun, die keine Koordination mit den Operationen erfordern. Zum Beispiel Geschirr spülen. Warum warten Sie im Leerlauf, während Sie den Toaster ständig anstarren, bis der Toast platzt, wenn Sie wissen, dass es einige Zeit dauern wird und Sie ein ganzes Gericht waschen können, während es fertig ist?

Hier kommen zwei weitere Lösungen ins Spiel, die als nicht blockierend bzw. asynchron bezeichnet werden.

Nicht blockierend ist, wenn Sie sich dafür entscheiden, andere Dinge zu tun, die nichts miteinander zu tun haben, während Sie auf den Vorgang warten. Überprüfen Sie die Verfügbarkeit der Antwort nach Belieben.

Also anstatt auf den Toaster zu schauen, damit er platzt. Du gehst und waschst ein ganzes Gericht. Und dann guckst du auf den Toaster, um zu sehen, ob die Toasts geplatzt sind. Wenn dies nicht der Fall ist, spülen Sie ein anderes Gericht und überprüfen den Toaster zwischen den einzelnen Gerichten. Wenn Sie sehen, dass die Toasts geplatzt sind, hören Sie auf, das Geschirr zu spülen. Stattdessen nehmen Sie den Toast und legen Butter darauf.

Es kann jedoch ärgerlich sein, ständig nach Toasts suchen zu müssen. Stellen Sie sich vor, der Toaster befindet sich in einem anderen Raum. Zwischen den Gerichten verschwenden Sie Ihre Zeit damit, in den anderen Raum zu gehen, um nach dem Toast zu sehen.

Hier kommt asynchron.

Asynchron ist, wenn Sie andere Dinge ausführen, die nichts miteinander zu tun haben, während Sie auf die Ausführung des Vorgangs warten. Anstatt es zu überprüfen, delegieren Sie die Überprüfungsarbeit an etwas anderes, das die Operation selbst oder ein Beobachter sein kann, und Sie werden von diesem Ding benachrichtigt und möglicherweise unterbrochen, wenn die Antwort verfügbar ist, damit Sie mit der anderen Operation fortfahren können brauchte es.

Es ist eine seltsame Terminologie. Das macht nicht viel Sinn, da all diese Lösungen eine asynchrone Koordination abhängiger Aufgaben ermöglichen. Deshalb nenne ich es lieber ereignisreich.

In diesem Fall entscheiden Sie sich, Ihren Toaster zu aktualisieren, damit er piept, wenn der Toast fertig ist. Sie hören ständig zu, auch wenn Sie Abwasch machen. Wenn Sie den Piepton hören, stehen Sie in Ihrer Erinnerung an, dass Sie anhalten und die Butter auf den Toast legen, sobald Sie mit dem Waschen Ihres aktuellen Gerichts fertig sind. Oder Sie können das Waschen des aktuellen Gerichts unterbrechen und sich sofort um den Toast kümmern.

Wenn Sie Probleme haben, den Piepton zu hören, können Sie Ihren Partner den Toaster für Sie ansehen lassen und Ihnen mitteilen, wann der Toast fertig ist. Ihr Partner kann selbst eine der drei oben genannten Strategien auswählen, um seine Aufgabe zu koordinieren, den Toaster zu beobachten und Ihnen mitzuteilen, wann er bereit ist.

Abschließend ist es gut zu verstehen, dass Sie, obwohl nicht blockierend und asynchron (oder was ich lieber als ereignisreich bezeichne), andere Dinge tun können, während Sie warten, dies aber nicht tun. Sie können festlegen, dass der Status eines nicht blockierenden Anrufs ständig wiederholt wird, ohne dass dies erforderlich ist. Das ist jedoch oft schlimmer als das Blockieren (wie das Betrachten des Toasters, dann weg, dann wieder zurück, bis es fertig ist), sodass Sie mit vielen nicht blockierenden APIs von dort in einen Blockierungsmodus wechseln können. Bei Ereignissen können Sie einfach im Leerlauf warten, bis Sie benachrichtigt werden. Der Nachteil in diesem Fall ist, dass das Hinzufügen der Benachrichtigung zunächst komplex und möglicherweise kostspielig war. Sie mussten einen neuen Toaster mit Signaltonfunktion kaufen oder Ihren Partner davon überzeugen, ihn für Sie anzusehen.

Und noch etwas: Sie müssen die Kompromisse erkennen, die alle drei bieten. Einer ist offensichtlich nicht besser als die anderen. Denken Sie an mein Beispiel. Wenn Ihr Toaster so schnell ist, haben Sie keine Zeit, ein Gericht zu spülen, und beginnen nicht einmal damit, es zu waschen. So schnell ist Ihr Toaster. In diesem Fall ist es nur eine Verschwendung von Zeit und Mühe, mit etwas anderem zu beginnen. Das Blockieren reicht aus. Wenn das Waschen eines Gerichts 10-mal länger dauert als das Toasten. Sie müssen sich fragen, was wichtiger ist, um fertig zu werden? Der Toast könnte zu diesem Zeitpunkt kalt und hart werden, es lohnt sich nicht, das Blockieren reicht auch aus. Oder Sie sollten schnellere Aufgaben auswählen, während Sie warten. Es ist offensichtlicher, aber meine Antwort ist schon ziemlich lang. Mein Punkt ist, dass Sie über all das nachdenken müssen und über die Komplexität der Implementierung, um zu entscheiden, ob es sich lohnt und ob es sich lohnt. '

Bearbeiten:

Obwohl dies bereits lang ist, möchte ich, dass es vollständig ist, also füge ich zwei weitere Punkte hinzu.

1) Es gibt üblicherweise auch ein viertes Modell, das als Multiplex bekannt ist . Dies ist der Fall, wenn Sie auf eine Aufgabe warten, eine andere starten und während Sie auf beide warten, eine weitere starten und so weiter, bis Sie viele Aufgaben gestartet haben und dann im Leerlauf warten, aber auf alle Sie. Sobald dies erledigt ist, können Sie mit der Bearbeitung der Antwort fortfahren und dann wieder auf die anderen warten. Es wird als Multiplex bezeichnet, da Sie während des Wartens jede Aufgabe nacheinander überprüfen müssen, um festzustellen, ob sie ad vitam erledigt ist, bis eine erledigt ist. Es ist eine Art Erweiterung über das normale Nicht-Blockieren hinaus.

In unserem Beispiel wäre es so, als würde man den Toaster starten, dann den Geschirrspüler, dann die Mikrowelle usw. Und dann auf einen von ihnen warten. Wo Sie den Toaster überprüfen würden, um festzustellen, ob er fertig ist, wenn nicht, würden Sie den Geschirrspüler überprüfen, wenn nicht, die Mikrowelle und wieder herum.

2) Obwohl ich glaube, dass es ein großer Fehler ist, wird synchron oft verwendet, um jeweils eine Sache zu bedeuten. Und viele Dinge gleichzeitig asynchron. Daher sehen Sie synchrones Blockieren und Nicht-Blockieren, um sich auf Blockieren und Nicht-Blockieren zu beziehen. Und asynchrones Blockieren und Nicht-Blockieren wird verwendet, um auf Multiplex und Evented zu verweisen.

Ich verstehe nicht wirklich, wie wir dorthin gekommen sind. Wenn es jedoch um E / A und Berechnung geht, beziehen sich synchron und asynchron häufig auf das, was besser als nicht überlappend und überlappend bekannt ist. Das heißt, asynchron bedeutet, dass sich E / A und Berechnung überlappen, auch bekannt als gleichzeitig. Während synchron bedeutet, dass dies nicht der Fall ist, geschieht dies nacheinander. Bei synchroner Nichtblockierung bedeutet dies, dass Sie keine anderen E / A-Vorgänge oder Berechnungen starten. Sie müssen nur warten und einen blockierenden Anruf simulieren. Ich wünschte, die Leute würden aufhören, so synchron und asynchron zu missbrauchen. Also ermutige ich es nicht.


Sie sind sich nicht sicher, warum Sie gesagt haben, dass "Synchron" gleichzeitig ausgeführt wird? "? Die ganze Idee ist, dass es nicht gleichzeitig ist, auch bekannt als nicht gleichzeitig.
Helsing

Es war eine großartige Analogie! Du hast es gerade geröstet!
D-Coder

@Helsing Das bedeutet wörtlich. Synchron bedeutet dieselbe Zeit und asynchron bedeutet nicht dieselbe Zeit: p. Der Grund, warum etwas asynchron ist, ist, dass es nicht gleichzeitig passieren kann, sondern vorher oder nachher passieren muss. Wenn es gleichzeitig passieren könnte, könnten Sie es einfach parallelisieren oder in beliebiger Reihenfolge ausführen, und Sie würden keine explizite Synchronisation benötigen. Deshalb geht es bei der asynchronen Programmierung darum, dies und das zu tun, auf diese Dinge zu warten und dann usw. Weil keines dieser Dinge gleichzeitig passieren kann.
Didier A.

@Helsing Gleichzeitiges ist auch nicht dasselbe wie parallel. Es bedeutet nicht, dass zwei Dinge gleichzeitig passieren, es bedeutet nur, dass Fortschritte bei mehr als einer Sache erzielt werden, bevor eines von ihnen beendet wird. Dies könnte durch Parallelisierung oder einfach durch Interleaving, auch bekannt als Task Switching, erreicht werden.
Didier A.

4

Anruf blockieren : Die Steuerung wird erst zurückgegeben, wenn der Anruf abgeschlossen ist.

Nicht blockierender Anruf: Die Steuerung kehrt sofort zurück. Das spätere Betriebssystem benachrichtigt den Prozess irgendwie, dass der Anruf abgeschlossen ist.


Synchrones Programm: Ein Programm, das Blocking Calls verwendet. Um während des Aufrufs nicht einzufrieren, müssen 2 oder mehr Threads vorhanden sein (deshalb heißt es Synchron - Threads werden synchron ausgeführt).

Asynchrones Programm: Ein Programm, das nicht blockierende Aufrufe verwendet. Es kann nur 1 Thread haben und trotzdem interaktiv bleiben.


1
Nicht blockierender Anruf: Die Steuerung kehrt zurück, nachdem so viel getan wurde, wie im Wesentlichen sofort möglich ist. Die Methode gibt an, wie viel getan wurde. Dies unterscheidet sich von einem asynchronen Aufruf, der sich so verhält, wie Sie es zum Blockieren des Anrufs beschrieben haben.
Supercat

0

Sie unterscheiden sich nur in der Schreibweise. Es gibt keinen Unterschied in dem, worauf sie sich beziehen. Um technisch zu sein, könnte man sagen, dass sie sich in ihrer Betonung unterscheiden. Nicht blockieren bezieht sich auf den Kontrollfluss (er blockiert nicht). Asynchron bezieht sich auf den Zeitpunkt, zu dem das Ereignis \ data behandelt wird (nicht synchron).


0

Bei den Blockierungsmodellen muss die initiierende Anwendung blockieren, wenn die E / A gestartet wurde. Dies bedeutet, dass es nicht möglich ist, Verarbeitung und E / A gleichzeitig zu überlappen. Das synchrone nicht blockierende Modell ermöglicht eine Überlappung von Verarbeitung und E / A, erfordert jedoch, dass die Anwendung den Status der E / A regelmäßig überprüft. Dadurch bleibt eine asynchrone, nicht blockierende E / A erhalten, die eine Überlappung von Verarbeitung und E / A ermöglicht, einschließlich einer Benachrichtigung über den Abschluss der E / A.


-2

Blockieren: Die Steuerung kehrt nach Abschluss der Verarbeitung des Grundelements (Synchronisierung oder Asynchronisierung) zum Aufrufen des Vorgangs zurück

Nicht blockierend: Die Steuerung kehrt unmittelbar nach dem Aufruf zum Prozess zurück


10
Dies beantwortet nicht einmal, was gefragt wird.
Koray Tugay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.