ソケットI / Oを効率的に行うことは、kqueue、epoll、IO完了ポートなどで解決されました。非同期ファイルI / Oの実行は、後発的なものです(WindowsのオーバーラップI / Oとposix AIOのソラリス初期サポートは別として)。
ソケットI / Oを行う場合は、上記のメカニズムのいずれかを使用する方がよいでしょう。
したがって、AIOの主な目的は、非同期ディスクI / Oの問題を解決することです。これは、Mac OS Xがソケットではなく通常のファイルのAIOのみをサポートする理由である可能性が最も高いです(kqueueはとにかく非常に優れているため)。
通常、書き込み操作はカーネルによってキャッシュされ、後でフラッシュされます。たとえば、ドライブの読み取りヘッドがブロックが書き込まれる場所をたまたま通過したとき。
ただし、読み取り操作の場合、カーネルに読み取りの優先順位を付けて順序付けする場合は、AIOが唯一のオプションです。カーネルがそれを(理論的に)他のユーザーレベルのアプリケーションよりもうまくできる理由は次のとおりです。
- カーネルは、アプリケーションのディスクジョブだけでなく、すべてのディスクI / Oを認識し、それらをグローバルレベルで注文できます。
- カーネルは、ディスク読み取りヘッドがどこにあるかを知っている可能性があり、ヘッドに最短距離を移動するために、そこに渡す読み取りジョブを最適な順序で選択できます
- カーネルはネイティブコマンドキューイングを利用して、読み取り操作をさらに最適化できます。
- 特に、読み取りが(論理的に)連続しておらず、システムコールのオーバーヘッドをわずかに節約できる場合は、lio_listio()を使用すると、システムコールごとにreadv()よりも多くの読み取り操作を発行できる場合があります。
- 読み取りまたは書き込みの呼び出しをブロックするために追加のスレッドを必要としないため、AIOを使用するとプログラムが少し単純になる可能性があります。
とは言っても、posix AIOは非常に扱いにくいインターフェースを持っています。例えば:
- イベントコールバックの唯一の効率的で十分にサポートされている手段は、シグナルを経由することです。これは、プロセスグローバルシグナル名前空間からのシグナル番号を使用することを意味するため、ライブラリでの使用を困難にします。お使いのOSがリアルタイム信号をサポートしていない場合は、未処理の要求をすべてループして、実際に終了した要求を特定する必要があることも意味します(これは、たとえばLinuxではなくMac OS Xの場合です)。マルチスレッド環境でシグナルをキャッチすると、いくつかのトリッキーな制限も発生します。通常、シグナルハンドラー内のイベントに反応することはできませんが、シグナルを発生させるか、パイプに書き込むか、またはLinuxでsignalfd()を使用する必要があります。
- lio_suspend()にはselect()と同じ問題があります。ジョブの数に応じて適切にスケーリングされません。
- lio_listio()は、実装されているため、渡すことができるジョブの数がかなり制限されており、移植可能な方法でこの制限を見つけることは簡単ではありません。sysconf(_SC_AIO_LISTIO_MAX)を呼び出す必要があります。これは失敗する可能性があります。その場合、必ずしも定義されていないAIO_LISTIO_MAX定義を使用できますが、サポートされることが保証されていると定義されている2を使用できます。
posix AIOを使用する実際のアプリケーションについては、サポートを導入するときにパフォーマンス測定値も投稿したlighttpd(lighty)をご覧ください。
ほとんどのposixプラットフォームは現在までにposix AIOをサポートしています(Linux、BSD、Solaris、AIX、tru64)。Windowsは、重複したファイルI / Oを介してそれをサポートします。私の理解では、Solaris、Windows、およびLinuxのみが本当に非同期をサポートしています。他のOSは非同期をエミュレートするのに対し、ファイルI / Oはドライバーまで続きます。カーネルスレッドによるI / O。Linuxは例外ですが、glibcのposix AIO実装はユーザーレベルのスレッドで非同期操作をエミュレートしますが、ネイティブの非同期I / Oインターフェイス(io_submit()など)は、ドライバーがサポートしていると仮定して、ドライバーまで完全に非同期です。
私は、どのfdについてもposix AIOをサポートせず、通常のファイルに制限することがOSの間でかなり一般的であると信じています。