Open Source Web Development Tutorials - Dev Shed
Linuxカーネルに与えるファイルI/Oのアドバイス
(2009/03/24公開)
Linuxカーネルに与えるファイルI/Oのアドバイス
これは全7回でLinux I/Oファイルのシステムコールを解説する連載の第5回です。今回は、Linuxカーネルにアドバイスを与える方法、そのほかを学習していきましょう。内容は、ロバート・ラブ著『Linux System Programming: Talking Directly to the Kernel and C Library(Linuxシステムプログラミング-カーネルおよびCライブラリへ直接話しかける:仮題)』第4章からの抜粋です。(原著はオライリーより2007年に出版、ISBN: 0596009585(Copyright 2007 O'Reilly Media, Inc.))禁無断転載。出版社の許可を得て使用しています。書店あるいはオライリーメディアから直接購入できます。
通常ファイルI/Oのアドバイス
前回では、メモリマッピングに関するアドバイスの指示方法を学習しました。今回では、カーネルに対して、通常のファイルI/Oをアドバイスする方法を学習します。通常のファイルI/Oをアドバイスする場合、Linuxにはposix_fadvise()およびreadahead()という2つのインターフェースがあります。
posix_fadvise( ) システムコール
1番目のアドバイス用インターフェースは、名前から推測できるように、POSIX 1003.1-2003の標準です。
#include <fcntl.h>
int posix_fadvise (int fd,
off_t offset,
off_t len,
int advice);
posix_fadvise()のコールは、カーネルに対して、[offset,offset+len)区間のファイル記述子fdに対する手掛かりadviceを与えます。lenがゼロの場合、アドバイスは[offset,length of file]値域に適用されます。lenおよびoffsetにゼロを指定して、ファイル全体にアドバイスを適用するのが一般的な利用法です。
adviceの選択肢は、madvise()の選択肢と同様です。adviceとして、以下のいずれかひとつを指示しなくてはなりません。
POSIX_FADV_NORMAL
このファイル値域に対して、明確に限定するアドバイスはありません。通常の処理を実行します。
POSIX_FADV_RANDOM
指示された値域内のデータに、順不同で(不連続的に)アクセスします。
POSIX_FADV_SEQUENTIAL
指示された値域内のデータに、低位アドレスから高位アドレスへの順で、連続的にアクセスします。
POSIX_FADV_WILLNEED
指示された値域内にあるデータに、近い将来アクセスします。
POSIX_FADV_NOREUSE
指示された値域内のデータに、近い将来、1回のみアクセスします。
POSIX_FADV_DONTNEED
指示された値域内のページに、近い将来アクセスする予定はありません。
madvise()と同じく、アドバイスに応えて、実装時固有の実反応が発生します。Linuxカーネルのバージョン次第で、異なる反応を示す可能性があります。現行の反応には、以下の種類があります。
POSIX_FADV_NORMAL
カーネルは通常どおりに動作して、中程度の先読みを実行します。
POSIX_FADV_RANDOM
カーネルは先読みを無効にして、おのおのの物理読み取り作業で最小限のデータ読み取りを実行します。
POSIX_FADV_SEQUENTIAL
カーネルは積極的な先読みを実行し、先読みウインドーを2倍の大きさに拡大します。
POSIX_FADV_WILLNEED
カーネルは先読みを起動して、指示されたページをメモリ内へ読み込みます。
POSIX_FADV_NOREUSE
現在のところ、POSIX_FADV_WILLNEEDと同じ動作です。将来のカーネルは、追加的な最適化を実行して、“use once(1回のみ使用)”動作を有効に生かすようになるかもしれません。この手掛かりにはmadvise()のコンプリメントはありません。
POSIX_FADV_DONTNEED
カーネルは、ページキャッシュから、指示された値域内のすべてのキャッシュされたデータを削除します。ほかの手掛かりと異なり、この手掛かりはmadvise()でのアドバイスとは動作が異なる点に留意してください。
一例を挙げましょう。以下のスニペットは、カーネルに対して、ファイル記述子fdで表されるファイル全体に順不同の不連続な方法でアクセスすることを指示しています。
int ret;
ret = posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM);
if (ret == -1)
perror ("posix_fadvise");
posix_fadvise()が成功すると、ゼロが戻ります。失敗すると-1が戻り、errnoが以下のいずれかの値を示します。
EBADF
指示されたファイル記述子が無効です。
EINVAL
指示されたアドバイスが無効です。あるいは、指示されたファイル記述子はパイプを参照します。あるいは、指示されたアドバイスを指示されたファイルに適用することはできません。
readahead( ) システムコール
posix_fadvise()システムコールは、2.6 Linuxカーネルで登場した新規のシステムコールです。以前は、readahead()システムコールを利用して、POSIX_FADV_WILLNEEDアドバイスとまったく同じ動作を実行させていました。posix_fadvise()とは異なり、readahead()はLinux固有のインターフェースです。
#include <fcntl.h>
ssize_t readahead (int fd,
off64_t offset,
size_t count);
readahead()のコールは、ファイル記述子fd から[offset,offset+count)領域をページキャッシュに投入します。
readahead()が成功するとゼロが戻ります。 失敗すると-1が戻り、errnoが以下のいずれかの値を示します。
EBADF
指示されたファイル記述子が無効です。
EINVAL
指示されたファイル記述子は、先読みをサポートするファイルへのマッピングを実行しません。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








