2016-03-31 8 views
0

Ich werde Aio für Async lesen verwenden. Wenn aio beendet ist und der Signal-Handler ausgelöst wurde, muss ich möglicherweise einen weiteren aio_read-Aufruf durchführen und fortfahren.aio_read innerhalb Signalhandler

aio_read wird nicht unter den Sicherheitsfunktionen (im Man-Signal) erwähnt. Gewöhnliches Lesen ist jedoch.

Welche Gefahren gibt es, nachfolgende aio_read Aufrufe in AIO Signal Handler zu tun?

+0

Aus [der 'aio_read'-Handbuchseite] (http://man7.org/linux/man-pages/man3/aio_read.3.html): "Simultane I/O-Operationen, die die gleiche'Aiocb'-Struktur angeben, erzeugen undefinierte Ergebnisse. " Wenn das Signal kommt, während ein anderer AIO-Aufruf mit der gleichen Kontrollstruktur ausgeführt wird, führt dies zu Problemen. Wenn Sie eine separate Kontrollstruktur und separate Puffer verwenden, sollte es sicher sein, ich * denke *. Ich weiß nicht, ob es Probleme mit der AIO-Signalisierung geben wird, wenn die Anfrage sofort beendet wird. –

+0

Könnten Sie stattdessen einen separaten Thread verwenden, der die Signale empfängt, z. ['sigwaitinfo()'] (http://man7.org/linux/man-pages/man2/sigwaitinfo.2.html)?Auf diese Weise könnten Sie eine neue Kontrollstruktur zuweisen (oder Mutexe verwenden), um die Verwendung einer bereits verwendeten Kontrollstruktur zu vermeiden. –

Antwort

3

Als Autor des vorgeschlagenen Boost.AFIO, der POSIX AIO nutzen kann, empfehle ich dringend, POSIX AIO überhaupt nicht zu verwenden. Ich bin kaum alleine in dieser Meinung, @arvid ist ähnlich gegen: http://blog.libtorrent.org/2012/10/asynchronous-disk-io/. Die API selbst ist schlecht entworfen und skaliert daher schlecht mit der Last, es sei denn, Sie verwenden betriebssystemspezifische Alternativen oder Erweiterungen für AIO wie BSD kqueues. POSIX AIO ist im Wesentlichen nutzlos wie es ist.

Darüber hinaus sind AIO-Aufrufe unter Linux, die Sie wahrscheinlich verwenden, nicht signalsicher. Dies liegt daran, dass sie unter Linux mit einer auf einem Threadpool basierenden Emulation im Userspace implementiert sind. Auf BSD haben AIO-Aufrufe eine richtige Kernel-Syscall-Schnittstelle, aber im Kernel verwandeln Sie sich in eine - ja, Sie haben es erraten - eine threadpoolbasierte Emulation, es sei denn, O_DIRECT ist eingeschaltet.

Sie sind daher viel besser auf POSIX einfach immer einen Threadpool verwenden, wenn alle Ihre E/A ist mit O_DIRECT auf. Wenn O_DIRECT in der Tat ist immer auf, Linux einen angepassten Kernel-API auf http://man7.org/linux/man-pages/man2/io_submit.2.html detailliert zur Verfügung, die ziemlich effektiv ist, und auf BSD , wenn Sie ersetzen Signal getriebenen Umgang mit BSD kqueues (https://www.freebsd.org/cgi/man.cgi?kqueue siehe EVFILT_AIO) dann mit O_DIRECT Dinge können auch gut skalieren, Besser als ein Threadpool.

Die Verwendung der Signal-basierten Completion-Behandlung auf jeder POSIX-Plattform hat schrecklichen Leistung. AFIO v2 bietet ein generisches POSIX AIO-Backend, und es ist schrecklich, schrecklich, schrecklich. Meide wie die Pest. Beachten Sie, dass ein threadgepoolter synchroner API-Entwurf portabel ist, gut skalierbar für die meisten Anwendungsfälle ist und was ich (und Arvid) jedem empfehlen würde, ohne hochspezialisierte Anforderungen wie das Schreiben eines Datenbank-Backends, wo Sie sehr strenge Kontrolle benötigen Die physische Speicherschicht und alles andere als O_DIRECT | O_SYNC ist keine Option.


Ok, alles, was gesagt, wenn Sie wirklich wirklich Signal angesteuert aio verwenden möchten, ich nehme an, das liegt daran, dass Sie Ihre Datei multiplexen möchten i/o mit nicht-Datei i/o Sachen und man kann deshalb Verwenden Sie aio_suspend(), das die richtige API dafür ist. Die Art und Weise, wie AFIO v2 dies behandelt, besteht darin, ein Echtzeit-Signal zu verwenden, um aio_suspend() zu unterbrechen, wenn etwas, das nicht mit aio zusammenhängt, verarbeitet werden muss, und aio_suspend() neu gestartet werden kann. Sie müssen sehr vorsichtig im Umgang mit Rennen und Deadlocks sein, und Sie müssen das Signal für den Thread, der aio_suspend() aufruft, sorgfältig maskieren und demaskieren, damit das Echtzeitsignal nicht verloren geht und Sie einen verlorenen Weckruf erhalten. Alles in allem lohnt es sich nicht für die normalerweise deutlich niedrigere I/O-Leistung, die Sie über eine threadpool + synchrone API erhalten.

Verwandte Themen