非同期 I/O (1/4)

はじめに

非同期 I/O は、時間のかかる I/O 操作を呼び出しをブロックさせずに行う方法です。Windows でサポートされている一般的な非同期 I/O を実現する方法は何種類かあります。ソケットでは非同期の方法がさらに増えますが、それはここでは取り扱いません。代表的なものに限定します。

特にこの資料ではサンプルコードを示します。その中で非同期 I/O を実際のコードに適用することを想定して、現実的なプログラムに適用するコツを併せてご説明します。

1. 非同期 I/O とは

非同期 I/O (Asynchronous I/O, MSDN ドキュメントの中では Overlapped I/O も非同期 I/O と翻訳されているようです) とは、I/O 操作の呼び出しをブロックしないで行うことです。例えば、遅いディスクから (フロッピーディスクみたいなのを想像してください) データを読み込むために ReadFile API を呼び出したとします。同期 I/O (Synchronous I/O) では指定した読み込みバイト数を読み込むまで、呼び出し側に制御が返りません。しかし、非同期 I/O では ReadFile API は、「処理待ち」 というステータスを返して直ちに制御を返します。制御が返るので、ReadFile がバックグラウンドでデータを読み込んでいる間、他の処理を行うことが可能となります。そ の後、 ReadFile が読み込みを完了したことを何らかの形で通知を受けます

通知を受ける方法によって、コーディング方法は様々です。通知を受ける方法のみならず、後述する I/O 完了ポート (I/O Completion Port) のように、OS がうまい具合に処理をやりくりしてくれる優れた方法もあります。

2. サンプルコード

この資料の中で使用しているサンプルコードは、次のようなものです。

三種類作りましたが、見た目はどれも上図のスクリーンショットと同様です。

From: にファイル名を指定し [OK] をクリックすると、C:\temp にテンポラリファイルを作成します。その名前が To: に表示されます。テンポラリファイルへ、From: で指定したファイルの内容を非同期 I/O を用いてコピーします。ですから、この図の場合、adf32C.tmp の中身は A:\app1.pdb と全く同一になります。

それぞれのプログラムにおいて、ReadFile または ReadFileEx を使って、ファイルの読み込み処理部分で非同期 I/O を利用しています

このとき、内部動作がある程度わかるように、デバッグトレースを出力するようにしています。デバッグトレースは Platform SDK 付属の dbmon や SysInternals の DebugView を使って見ることが出来ます。DebugView を使ってトレースを確認すると下記のようになります。

このように OK!! と出ると正常終了です。

それでは早速、実際にコードを見ながら非同期 I/O の例を見ていきましょう。それと共に、それぞれの方法に特有の技術背景についてもポイントを説明します。(詳細は MSDN や参考資料をお読みください)

ここで取り上げるのは、次の三つの例です。

1.基本的な非同期 I/O
2.完了ルーチンを用いる非同期 I/O
3.I/O 完了ポートを用いた非同期 I/O

※ この先長くなりますので、次のトピックへ分けます...

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説