Rustでの非同期IOの実装に関するこの講演を見ていましたが、Carlは2つの潜在的なモデルに言及しています。準備と完了。
準備モデル:
- ソケットから読み取ることをカーネルに指示します
- しばらく他のことをする…
- カーネルは、ソケットの準備ができたときに通知します
- あなたが読む(バッファを埋める)
- 必要なことは何でもしてください
- バッファーを解放します(Rustで自動的に発生します)
完了モデル:
- カーネルが満たすようにバッファを割り当てます
- しばらく他のことをする…
- カーネルは、バッファがいっぱいになると通知します
- データで必要なことを何でもする
- バッファを解放する
レディネスモデルを使用するCarlの例では、使用可能なメモリを反復処理して、グローバルバッファを埋め、解放することで、メモリの使用量を大幅に減らすことができます。
今私の仮定:
ソケットが「準備完了」であると言われる内部(カーネル空間内)では、データは既に存在します。ネットワーク経由で(またはどこからでも)ソケットに入り、OSはデータを保持しています。
そのメモリ割り当てがレディネスモデルで魔法のように行われないというわけではありません。OSがそれをあなたから抽象化しているだけです。完了モデルでは、OSは、データが実際に流入する前にメモリを割り当てるように求めており、何が起きているかが明らかです。
準備モデルの修正版は次のとおりです。
- ソケットから読み取ることをカーネルに指示します
- しばらく他のことをする…
- 修正:データはOSに送られます(カーネルメモリの一部)
- カーネルは、ソケットの準備ができたことを通知します
- 読み取ります(上記のカーネルバッファーとは別のバッファーを埋めます(または、ポインターを取得しますか?))
- 必要なことは何でもしてください
- バッファーを解放します(Rustで自動的に発生します)
/私の仮定
私はたまたまユーザースペースプログラムを小さく保つのが好きですが、実際にここで何が起こっているのかを明確にしたかったのです。1つのモデルが本質的に少ないメモリを使用したり、より高いレベルの同時IOをサポートしたりすることはありません。私はこれについての考えとより深い説明を聞きたいです。