Werden alle asynchronen E / A letztendlich beim Abruf implementiert?

8

Ich habe festgestellt, dass asynchrone I / O immer ein Callback-Formular hat. Aber kürzlich entdeckte ich, dass einige Low-Level-Implementierungen die Polling-API verwenden.

  1. kqueue
  2. libpq

Und das führt mich zu der Annahme, dass möglicherweise alle (oder die meisten) asynchronen E / A (Datei, Socket, Mach-Port usw.) in einer Art Polling-Art implementiert werden. Vielleicht ist das Callback-Formular nur eine Abstraktion nur für eine höhere API.

Das könnte eine dumme Frage sein, aber ich weiß nicht, wie eigentlich die meisten asynchronen I / O auf niedrigem Niveau implementiert sind. Ich habe nur die Benachrichtigungen auf Systemebene verwendet, und wenn ich kqueue sehe - was die Systembenachrichtigung ist, ist das ein Abfragestil!

Wie soll ich asynchrone E / A auf niedriger Ebene verstehen? Wie wird die asynchrone Benachrichtigung auf höchster Ebene von einem Abfragesystem auf niedriger Ebene erstellt? (falls dies tatsächlich der Fall ist)

    
Eonil 16.10.2013, 04:22
quelle

1 Antwort

11

Bei der niedrigsten (oder zumindest niedrigsten) Hardwareebene sind asynchrone Operationen in modernen Betriebssystemen wirklich asynchron.

Wenn Sie z. B. eine Datei von der Festplatte lesen, übersetzt das Betriebssystem Ihren Aufruf in read in eine Reihe von Festplattenoperationen (Suche nach Speicherplatz, Lesen der Blöcke X bis Y usw.). Auf den meisten modernen Betriebssystemen werden diese Befehle entweder in spezielle Register oder spezielle Speicherorte im Hauptspeicher geschrieben, und der Plattencontroller wird informiert, dass Vorgänge ausstehen. Das Betriebssystem geht dann weiter und wenn der Plattencontroller alle ihm zugewiesenen Operationen abgeschlossen hat, löst er eine Unterbrechung , wodurch der Thread, der die Leseanforderung angefordert hat, an der Stelle abgeholt wird, an der er unterbrochen wurde.

Unabhängig von der Art der asynchronen Low-Level-Operation (Datenträger-E / A, Netzwerk-E / A, Maus- und Tastatureingabe usw.) gibt es letztendlich einen Zeitpunkt, an dem ein Befehl ausgelöst wird an die Hardware, und der "Callback" wird sozusagen nicht ausgeführt, bis die Hardware das Betriebssystem erreicht hat, und informiert das Betriebssystem, normalerweise in Form eines Interrupts.

Das soll nicht heißen, dass keine asynchronen Operationen mit Polling implementiert wurden. Eine triviale (aber naive und kostspielige) Möglichkeit, blockierende Operationen asynchron zu implementieren, besteht darin, einen Thread zu erzeugen, der darauf wartet, dass die Operation abgeschlossen wird (vielleicht in einer engen Schleife) und dann den Callback aufruft, wenn er beendet ist. Im Allgemeinen sind gemeinsame asynchrone Operationen auf Betriebssystemebene jedoch wirklich asynchron.

Es ist auch erwähnenswert, dass, nur weil eine API blockiert, nicht bedeutet, dass sie polling: Sie können eine blockierende API auf eine asynchrone Operation und eine nicht blockierende API auf eine synchrone Operation setzen. Mit Dingen wie select und kqueues zum Beispiel geht der Thread tatsächlich in den Ruhezustand, bis etwas Interessantes passiert. Dieses "etwas Interessantes" kommt (normalerweise) in Form eines Interrupts zustande, und das wird als ein Hinweis darauf angesehen, dass das Betriebssystem die relevanten Threads zum Fortsetzen der Arbeit aufwecken sollte. Es sitzt nicht nur in einer engen Schleife und wartet darauf, dass etwas passiert.

Es gibt wirklich keine Möglichkeit zu sagen, ob ein System Polling oder "echte" Callbacks (wie Interrupts) nur von seiner API verwendet, aber ja, es gibt asynchrone APIs, die wirklich von asynchronen Operationen unterstützt werden.

    
Matt Patenaude 16.10.2013, 04:45
quelle

Tags und Links