マルチスレッドのプログラミング

非同期入出力操作


#include <sys/asynch.h>

int aioread(int fildes, char *bufp, int bufs, off_t offset,
    int whence, aio_result_t *resultp);

int aiowrite(int filedes, const char *bufp, int bufs,
    off_t offset, int whence, aio_result_t *resultp);

aio_result_t *aiowait(const struct timeval *timeout);
int aiocancel(aio_result_t *resultp);

aioread(3)aiowrite(3) の形式は、pread(2)pwrite(2) の形式にそれぞれ似ています。違いは、引数リストの最後に引数が 1 つ追加されていることです。aioread() または aiowrite() を呼び出すと、入出力操作が開始されます (あるいは、入出力要求が待ち行列に入れられます)。

この呼び出しはブロックされずに復帰し、resultp の指す構造体に終了状態が戻されます。これは aio_result_t 型の項目で、次のフィールドで構成されています。


int aio_return;
int aio_errno;

呼び出しが失敗すると、aio_errno にエラーコードが設定されます。そうでない場合は、このフィールドには操作要求が正常に待ち行列に入れられたことを示す AIO_INPROGRESS が設定されます。

非同期入出力操作の完了は、aiowait(3) で待つことができます。この関数は、最初の aioread(3)、または aiowrite(3) で指定した aio_result_t 構造体へのポインタを返します。

この時点で aio_result_t には、read(2) または write(2) のどちらかが非同期バージョン以外で呼ばれた時と同じ情報が設定されます。この read または write が正常終了した場合、aio_return には読み書きされたバイト数が設定されます。異常終了した場合、aio_return には -1、aio_errno にはエラーコードが設定されます。

aiowait() には timeout 引数があり、呼び出し側の待ち時間を設定できます。ここに NULL ポインタを指定すれば、無期限に待つという意味になります。また、値 0 が設定されている構造体を指すポインタの場合は、まったく待たないという意味になります。

非同期入出力操作を開始し別の処理を行なって aiowait() で操作の完了を待つ、あるいは操作完了時に非同期的に送られてくる SIGIO を利用するという方法もあります。

保留状態の入出力操作を取り消すときは、aiocancel() を使用します。このルーチンを呼び出すときは、取り消そうとする非同期入出力操作の結果を格納するアドレスを引数で指定します。