Frage

Es gibt im Internet verstreute Seiten, die die POSIX-AIO-Funktionen unterschiedlich detailliert beschreiben.Keiner von ihnen ist besonders neu.Es ist nicht klar, was genau sie beschreiben.Zum Beispiel der „offizielle“ (?) Website für asynchrone I/O-Unterstützung im Linux-Kernel finden Sie hier sagt, dass Sockets nicht funktionieren, aber die „aio.h“-Handbuchseiten auf meiner Ubuntu 8.04.1-Workstation scheinen alle darauf hinzudeuten, dass es für beliebige Dateideskriptoren funktioniert.Dann gibt es ein weiteres Projekt, das auf Bibliotheksebene zu funktionieren scheint mit noch weniger Dokumentation.

Ich würde gerne wissen:

  • Was ist der Zweck von POSIX AIO?Angesichts der Tatsache, dass das offensichtlichste Beispiel einer Implementierung, das ich finden kann, besagt, dass sie keine Sockets unterstützt, kommt mir die ganze Sache seltsam vor.Gilt es nur für asynchrone Festplatten-E/A?Wenn ja, warum die hypergenerische API?Wenn nicht, warum wurde dann zuerst Festplatten-I/O angegriffen?
  • Wo gibt es Beispiele? vollständig POSIX AIO-Programme, die ich mir ansehen kann?
  • Benutzt es tatsächlich irgendjemand?
  • Welche Plattformen unterstützen POSIX AIO?Welche Teile davon unterstützen sie?Unterstützt jemand wirklich das implizite „Any I/O to any FD“? <aio.h> scheint zu versprechen?

Die anderen Multiplexing-Mechanismen, die mir zur Verfügung stehen, sind vollkommen gut, aber die zufälligen Informationsfragmente, die da draußen herumschwirren, haben mich neugierig gemacht.

War es hilfreich?

Lösung

Network I / O ist keine Priorität für AIO weil jeder POSIX Netzwerk-Server zu schreiben verwendet ein Ereignis basiert, nicht blockierenden Ansatz. Das im alten Stil Java „Milliarden von Threads blockiert“ -Ansatz saugt schrecklich.

Disk-Schreib-I / O bereits gepuffert und Platte gelesen I / O-Prefetch in den Puffer werden kann Funktionen wie posix_fadvise verwenden. Das lässt direkte, ungepufferte Disk-I / O als einzig sinnvollen Zweck für AIO.

Direct, ungepufferte E / A ist nur dann wirklich nützlich für die Transaktionsdatenbanken, und diejenigen, neigen dazu, ihre eigenen Threads oder Prozesse zu schreiben ihre Platten-I / O zu verwalten.

Also, am Ende, dass POSIX AIO in der Lage, nicht dienen alle nützlichen Zweck verläßt. Verwenden Sie es nicht.

Andere Tipps

Die effiziente Durchführung von Socket-I/O wurde mit kqueue, epoll, IO-Completion-Ports und dergleichen gelöst.Die Durchführung asynchroner Datei-E/A ist eine Art Nachzügler (abgesehen von der überlappenden E/A von Windows und der frühen Unterstützung von Posix AIO durch Solaris).

Wenn Sie Socket-I/O durchführen möchten, ist es wahrscheinlich besser, einen der oben genannten Mechanismen zu verwenden.

Der Hauptzweck von AIO besteht daher darin, das Problem der asynchronen Festplatten-E/A zu lösen.Dies ist höchstwahrscheinlich der Grund, warum Mac OS X AIO nur für reguläre Dateien und nicht für Sockets unterstützt (da kqueue das sowieso viel besser macht).

Schreibvorgänge werden normalerweise vom Kernel zwischengespeichert und zu einem späteren Zeitpunkt gelöscht.Zum Beispiel, wenn der Lesekopf des Laufwerks zufällig an der Stelle vorbeifährt, an der der Block geschrieben werden soll.

Wenn Sie jedoch möchten, dass der Kernel Ihre Lesevorgänge priorisiert und ordnet, ist AIO bei Lesevorgängen tatsächlich die einzige Option.Hier erfahren Sie, warum der Kernal dies (theoretisch) besser kann als jede andere Anwendung auf Benutzerebene:

  • Der Kernel sieht alle Festplatten-I/Os, nicht nur die Festplattenjobs Ihrer Anwendungen, und kann sie auf globaler Ebene ordnen
  • Der Kernel weiß möglicherweise, wo sich der Lesekopf der Festplatte befindet, und kann die Leseaufträge, die Sie an ihn weiterleiten, in der optimalen Reihenfolge auswählen, um den Kopf auf dem kürzesten Weg zu bewegen
  • Der Kernel kann davon profitieren native Befehlswarteschlange um Ihre Lesevorgänge weiter zu optimieren
  • Möglicherweise können Sie mit lio_listio() mehr Lesevorgänge pro Systemaufruf ausführen als mit readv(), insbesondere wenn Ihre Lesevorgänge nicht (logisch) zusammenhängend sind, wodurch ein wenig Systemaufruf-Overhead eingespart wird.
  • Ihr Programm könnte mit AIO etwas einfacher sein, da Sie keinen zusätzlichen Thread benötigen, um einen Lese- oder Schreibaufruf zu blockieren.

Allerdings verfügt Posix AIO über eine recht umständliche Benutzeroberfläche, zum Beispiel:

  • Die einzige effiziente und gut unterstützte Methode für Ereignisrückrufe sind Signale, was die Verwendung in einer Bibliothek erschwert, da hierfür Signalnummern aus dem prozessglobalen Signal-Namespace verwendet werden müssen.Wenn Ihr Betriebssystem keine Echtzeitsignale unterstützt, bedeutet das auch, dass Sie alle ausstehenden Anfragen durchgehen müssen, um herauszufinden, welche tatsächlich abgeschlossen wurde (dies ist beispielsweise bei Mac OS X der Fall, nicht bei Linux).Das Abfangen von Signalen in einer Multithread-Umgebung bringt auch einige knifflige Einschränkungen mit sich.Normalerweise können Sie nicht auf das Ereignis innerhalb des Signalhandlers reagieren, sondern müssen ein Signal auslösen, in eine Pipe schreiben oder signalfd() (unter Linux) verwenden.
  • lio_suspend() hat die gleichen Probleme wie select(), es lässt sich jedoch nicht sehr gut mit der Anzahl der Jobs skalieren.
  • In der implementierten Version von lio_listio() ist die Anzahl der Jobs, die Sie übergeben können, ziemlich begrenzt, und es ist nicht trivial, diese Grenze auf portable Weise zu ermitteln.Sie müssen sysconf(_SC_AIO_LISTIO_MAX) aufrufen, was möglicherweise fehlschlägt. In diesem Fall können Sie die Definition AIO_LISTIO_MAX verwenden, die nicht unbedingt definiert ist, aber dann können Sie 2 verwenden, die als garantiert unterstützt definiert ist.

Was reale Anwendungen mit Posix AIO betrifft, können Sie einen Blick auf lighttpd (lighty) werfen, das ebenfalls einen Beitrag veröffentlicht hat Leistungsmessung bei der Einführung von Unterstützung.

Die meisten Posix-Plattformen unterstützen mittlerweile Posix AIO (Linux, BSD, Solaris, AIX, tru64).Windows unterstützt es über seine überlappende Datei-E/A.Meines Wissens nach unterstützen nur Solaris, Windows und Linux Async wirklich.Datei-E/A bis hinunter zum Treiber, während die anderen Betriebssysteme die Asynchronität emulieren.I/O mit Kernel-Threads.Linux bildet eine Ausnahme. Seine Posix-AIO-Implementierung in Glibc emuliert asynchrone Vorgänge mit Threads auf Benutzerebene, während seine native asynchrone I/O-Schnittstelle (io_submit() usw.) bis hinunter zum Treiber wirklich asynchron ist, sofern der Treiber dies unterstützt .

Ich glaube, dass es unter Betriebssystemen ziemlich üblich ist, Posix AIO für kein FD zu unterstützen, sondern es auf reguläre Dateien zu beschränken.

Ein libtorrent Entwickler liefert einen Bericht über diese: http: // blog. libtorrent.org/2012/10/asynchronous-disk-io/

Es gibt aio_write - in glibc umgesetzt werden; erster Aufruf der aio_read oder aio_write Funktion laicht eine Anzahl von Benutzermodus Threads, aio_write oder aio_read Post-Anfragen zu diesem Thread, der Thread tut pread / pwrite und wenn es die Antwort abgeschlossen ist, wird wieder in dem gesperrten Aufruf Thread gepostet.

Ther ist auch 'echte' aio - vom Kernel-Ebene unterstützt (müssen libaio dafür finden Sie in der io_submit Aufruf http://linux.die.net/man/2/io_submit ); auch muß O_DIRECT für die (auch von allen Dateisystemen nicht unterstützt werden, aber die wichtigsten ist es unterstützen)

siehe hier:

http://lse.sourceforge.net/io/aio.html

http://linux.die.net/man/2/io_submit

Unterschied zwischen POSIX AIO und libaio auf Linux?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top