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