AIO 要求での入出力完了ポートの使用
AIO 要求で入出力完了ポート (IOCP) を使用するには、 aio_flags フィールドおよび aio_version フィールドの AIO_EXTENDED フラグを AIOCBX_VERS2 以上の値に設定します。 定義されている他のすべての拡張フィールドは、使用しない場合は 0 に設定する必要があります。
この拡張機能では、以下のフィールドが使用されます。
| フィールド | バージョン |
|---|---|
| aio_iocpfd | AIOCBX_VERS2 |
スレッド化された環境で使用される AIO インターフェースの制限は、 aio_nwait() が同じプロセス内のすべてのスレッドについて完了した入出力要求を収集することです。 言い換えると、1 つのスレッドが、別のスレッドによって実行依頼された完了済み入出力要求を収集します。 もう 1 つの問題は、複数のスレッドが同時にコレクション・ルーチン ( aio_nwait()など) を呼び出すことができないことです。 あるスレッドが aio_nwait() を発行し、別のスレッドがそれを呼び出している場合、2 番目の aio_nwait() は EBUSYを返します。 この制限は、多数の入出力を同時に実行する必要があり、単一スレッドが完了したすべての入出力を収集するのに十分な速さで実行できない場合に、入出力パフォーマンスに影響を与える可能性があります。
AIO 要求で入出力完了ポートを使用すると、アプリケーションはマルチスレッド環境でさまざまな AIO 操作の結果をスレッド単位で取り込むことができます。 この機能は、スレッドによって開始された AIO 要求のみの完了状況を受け取る方法をスレッドに提供します。
IOCP サブシステムは、AIO 要求の完了パケットを生成することによって、完了状況のみを提供します。 IOCP を介して通常のファイルに対して入出力を実行依頼することはできません。
AIO の現在の動作は変更されません。 アプリケーションは、入出力完了ポートと組み合わせて既存の AIO インターフェースを自由に使用できます。 アプリケーションは、完了ポートに関連付けられた、取り消されていない AIO 要求の完了パケットを「取得」する責任があります。
アプリケーションは、 CreateIoCompletionPort IOCP ルーチンを使用して、ファイルを完了ポートに関連付ける必要があります。 ファイルは複数の完了ポートに関連付けることができ、1 つの完了ポートに複数のファイルを関連付けることができます。 関連付けを行う場合、アプリケーションは、AIO 完了パケットとソケット完了パケットを区別するために、アプリケーション定義の CompletionKey を使用する必要があります。 アプリケーションは、必要に応じて異なる CompletionKeys を使用して、個々のファイルを (またはその他の方法で) 区別することができます。
また、アプリケーションは、対応するファイルと同じ完了ポートに AIO 要求を関連付ける必要があります。 これを行うには、完了ポートのファイル記述子を使用して AIOCB の aio_iocpfd を初期化します。 AIOCB は 1 つの完了ポートにのみ関連付けることができますが、1 つの完了ポートに複数の AIOCB を関連付けることができます。 完了ポートと AIOCB の間の関連付けを行う必要があります。 前 要求が行われます。 これは、 aio_write、 aio_read、または lio_listioなどの AIO ルーチンを使用して行われます。 aio_iocpfd フィールドの値が有効な完了ポート・ファイル記述子でない場合、要求を開始しようとしても失敗し、入出力は実行されません。
関連付けは、完了ポートと AIOCB の間で直接行う必要があります。 例えば、 lio_listio()を呼び出す場合は、呼び出しの前に、 lio_listio チェーン内の各 AIOCB を個別に関連付ける必要があります。 チェーン内のすべての AIOCB が完了ポートに関連付けられている必要はありません。
関連付けが作成された後、アプリケーションが aio_iocpfd フィールドに値 0 を使用して明示的にクリアするか、AIOCB が破棄されるまで、関連付けは残ります。 完了パケットは、完了ポートに関連付けられている AIOCB の入出力が完了したときにのみ作成されます。
- 通常のファイルを入出力用にオープンします。
- CreateIoCompletionPortルーチンを呼び出して、通常のファイルのファイルディスクリプタとアプリケーション定義のCompletionKey を使用して I/O 完了ポート(IOCP)を作成する。 CreateIoCompletionPort 関数は、新しく作成された IOCP に対応する IOCP ファイル記述子を戻します。
- AIO 制御ブロックを割り振り、( bzero 機能を使用して) クリアします。 AIOCB の aio_flags フィールドの AIO_EXTENDED フラグを設定することによって、入出力完了ポートが AIO 要求で使用されることを示します。 また、 aio_version フィールドを
AIOCBX_VERS2以上の値に設定します。 - CreateIoCompletionPort ルーチンによって戻される IOCP ファイル記述子を入れるために、AIOCB 内の aio_iocpfd フィールドを初期設定することによって、AIO 要求を IOCP に関連付けます。
- 既存の AIO インターフェースを使用して AIO 要求を開始します。 lio_listio インターフェースを使用して、複数の要求を開始できます。
- IOCP ファイル記述子を指定して GetQueuedCompletionStatus 関数を呼び出し、特定の IOCP で完了した AIO 要求の結果を収集します。 アプリケーションはポインターのアドレスを GetQueuedCompletionStatusに提供します。したがって、対応する AIOCB ポインターを戻すことができます。 AIO 要求の詳細は、返された AIOCB を調べることによって判別できます。
- すべての入出力が完了した後、アプリケーションはすべてのファイル・ディスクリプターをクローズする必要があります。