最新の Linux カーネルでの aio のカーネル サポートの状態に関する最新情報を入手できる場所を知っている人はいますか? Google 検索では、どうしようもなく古い Web ページが表示されます。
編集:
より具体的には、パイプやソケットなど、ファイルに関連しない記述子に興味があります。Web 上の情報では、サポートがないことが示されていますが、これはまだ当てはまりますか?
Edit2:私が探しているのは、Windows OVERLAPPED IO に似たものです
ソケットとパイプを非同期的に使用するために POSIX AIO (つまり man aio) は必要ありません。それによると、man 3 aio
それさえ不可能です。、、などのイベント通知インターフェイスとともに、代わりにノンブロッキング ファイル記述子を使用する必要があります。は Linux 固有ですが、前の 2 つよりもはるかに優れた拡張性があります。select()
poll()
epoll
epoll
非ブロッキング モードでファイル記述子を使用するにはO_NONBLOCK
、すべてのファイル記述子にフラグを設定する必要があります。
fcntl(fd, F_SETFL, O_NONBLOCK)
ファイル記述子が非ブロッキング モードになった後、およびのような I/O 操作read()
はブロックされませんが、操作をすぐに完了できない場合はorwrite()
が返されます。などのより具体的な操作は、ノンブロッキング モードでは別の方法で使用する必要があります。関連する man ページを参照してください。EAGAIN
EWOULDBLOCK
connect()
ノンブロッキング ファイル記述子を正しく使用できるようにするには、アプリケーションをイベント ドリブンにする必要があります。基本的に、 では、最初に初期化を行い、次にイベント ループmain()
に入る必要があります。イベント ループは、(イベント通知インターフェイスなどを使用して) イベントを繰り返し待機し、発生したイベントを確認して応答します。epoll_wait()
と言ってread()
で失敗するとEWOULDBLOCK
、可読性を監視するファイル記述子のリストに追加します。イベント プロバイダーが可読性を示している場合は、再試行します。
同様に、 を試みてwrite()
で失敗した場合はEWOULDBLOCK
、データをバッファリングして、書き込み可能であることが示されたら再試行することをお勧めします。
Linux には2種類の AIO があります。
1 つはカーネル AIO です。見苦しく、ドキュメントに従って動作しない場合があります (たとえば、特定の条件下で何もできなくても同期的に実行されたり、特定の条件下で進行中のリクエストを適切にキャンセルしたりしないなど)。等)。パイプでは機能しません。
これらはio_
関数の一種です。-laio
一部のシステム (Debian/Ubuntu など) では個別にインストールする必要がある とリンクする必要があることに注意してください。
2 つ目は、要求を処理するためにオンデマンドでスレッドを生成する純粋なユーザーランド実装 (glibc) です。それは十分に文書化されており、かなりうまく機能し、ドキュメントによると、pipes を含むファイル記述子であるほとんどすべてで機能します。
これらはaio_
関数の一種です。「クールでないユーザーランドの実装」であっても、これらを使用することを強くお勧めします。うまく機能します。
どちらも当面は通知メカニズムとして eventfd で動作しますが、前回調べたときはカーネルのバージョンはまだ文書化されていませんでした (ただし、関数はヘッダーにあります)。
または、Ambroz Bizjak が指摘したように、AIO をまったくスキップしてください。
編集:
別のメモとして、「パイプ」と「ソケット」という言葉を使用したため、vmspliceとspliceを認識していますか? これらは、ソケット/パイプとの間でデータを送受信するためのおそらく最も効率的な機能です。残念ながら、これはあいまいに文書化された、あいまいな落とし穴のあるハッキングを理解するのが難しい別の 1 つです。警告を受けていますので、自己責任で進めてください。
splice
ソケット(または任意のファイル記述子)からパイプに、またはその逆にデータを転送できます。vmsplice
アプリケーション空間とパイプの間でデータを転送できます。
皮肉なことに、vmsplice
理想的には、2006 年に BSD 開発者は全員ばかだと主張する特定の人物が主張したのとまったく同じこと (ページのリマップ、別名「VM で遊ぶ」) を行うことになっています。
良いニュースはこれだけですが、悪いニュースは、移動できるデータ量には「秘密の制限」があることです。私が覚えている限り、それは 64kB です (ただし、/proc のどこかで構成可能です)。したがって、それよりも多くのデータがある場合は、おそらく複数のパイプ バッファーを使用して、いくつかのチャンクで作業する必要があります。一方が読み込まれている間、もう一方が読み込まれ、完了後に古いパイプ バッファーが再利用されます。
そして、これが複雑になるところです。Kernel Trap の議論を参照すると、Grand Master でさえ、複数のバッファーを操作するときに古いバッファーを上書きしても安全な時期について 100% 確信が持てないことがわかります。
また、実際vmsplice
に機能させるには(つまり、コピーする代わりにページを再マッピングする)、「GIFT」フラグを使用する必要があります。少なくとも私には、そのメモリがどうなるかドキュメントからは明らかではありません。手紙のドキュメントに従うと、二度と触れることができないため、メモリをリークする必要があります。もちろんそれはあり得ません。多分私はただ愚かです。
私は最終的にこれをあきらめ、epoll
単純な normal で準備とノンブロッキングソケットを使用することに落ち着きましwrite
た。この組み合わせは最高のパフォーマーではないかもしれませんが、十分に文書化されており、文書化されているとおりに機能します。
AIO サポートは、Linux カーネル自体に含まれています。そのため、Google での最初のヒットは 2.4 Linux カーネルへのパッチのみを提供しています。2.6 と 3.0 では、すでにそこにあります。
Linux カーネルのソース コードをチェックアウトすると、fs/aio.c にあります。
GNU libc manual にいくつかのドキュメントがありますが、すべてのタイプの Linux ファイル記述子で aio が使用できるわけではないことに注意してください。一般的な「ハウツー」ドキュメントのほとんどは2006 年頃に作成されています。これは、Linux の AIO が見出しを飾っていた時期であるため、適切です。
POSIX.1b および Unix98 標準は変更されていないことに注意してください。そのため、例の「時代遅れ」の性質について少し具体的に説明できますか?