Open Source Web Development Tutorials - Dev Shed
Linuxカーネルに与えるファイルI/Oのアドバイス
(2009/03/24公開)
非同期I/O
非同期I/Oを実行するには、カーネル最下位層のサポートが必要です。POSIX 1003.1-2003は、ありがたいことにLinuxが実装しているaioインターフェースを定義します。以下のように、aioライブラリには、非同期I/Oを提出して完了時に通知を受け取る関数ファミリがあります。
#include <aio.h>
/* asynchronous I/O control block */
struct aiocb {
int aio_filedes; /* file descriptor */
int aio_lio_opcode; /* operation to perform */
int aio_reqprio; /* request priority offset */
volatile void *aio_buf; /* pointer to buffer */
size_t aio_nbytes; /* length of operation */
struct sigevent aio_sigevent; /*
signal number and value */
/* internal, private members follow... */
};
int aio_read (struct aiocb *aiocbp);
int aio_write (struct aiocb *aiocbp);
int aio_error (const struct aiocb *aiocbp);
int aio_return (struct aiocb *aiocbp);
int aio_cancel (int fd, struct aiocb *aiocbp);
int aio_fsync (int op, struct aiocb *aiocbp);
int aio_suspend (const struct aiocb * const cblist[],
int n,
const struct timespec *timeout);
スレッドベースの非同期I/O
LinuxはO_DIRECTフラグで開いたファイルのaioのみをサポートします。O_DIRECTを使わずに開いた通常ファイルで非同期I/Oを実行するには、自分で方法を探さなくてはなりませんが、カーネルのサポートがないため、本物の非同期I/Oに類似した結果を出してくれる近似の非同期I/Oを採用するしかありません。
最初に、なぜ、アプリケーション開発者は非同期I/Oを希望するのでしょうか?以下がその理由です。
・ブロッキングなしでI/Oを実行するため
・I/Oを待ち行列に入れる、I/Oをカーネルに提出する、動作完了の通知を受け取る-これらの活動を分離するため
1番目は性能の問題です。I/O動作がまったくブロックしなければ、入出力のオーバーヘッドはゼロになり、I/O制約のプロセスとならずにすみます。2番目は手順の問題であり、単にI/Oの処理方法が違うだけです。
これらの目標を実現するもっとも一般的な方法は、スレッド(スケジューリングに関しては、第5章と第6章で解説します)を利用する方法です。この方法には、以下のプログラミングが含まれます。
1.すべてのI/Oを処理するために、「ワーカースレッド」のプールを作成する
2.I/O動作をワークキューに置くためのインターフェースセットを実装する
3.これらインターフェースのおのおのに、関連付いたI/O動作を一意的に特定するI/O記述子を戻させる。各ワーカースレッドで、キューの先頭からI/O要求を取り込み、提出して、完了を待つ
4.完了したら、動作結果(戻り値、エラーコード、すべての読み込みデータ)を結果キューへ置く
5.結果キューからステータス情報を読み出すインターフェースセットを実装し、最初に戻されたI/O記述子を使って各動作を特定する
この方法を使えば、スレッド管理というオーバーヘッドが増大するものの、POSIXのaioインターフェースと同様の動作を実現することができます。
では、次のパートで学習を続けましょう。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








