Open Source Web Development Tutorials - Dev Shed
Linux I/Oファイルのシステムコール
(2009/03/03公開)
戻り値
成功した場合、readv()およびwritev()は、それぞれ、読み出したバイト数あるいは書き込んだバイト数を戻します。この数値は、count iov_lenの全数値の合計です。エラーが発生した場合、システムコールはreturn-1を戻し、適切なerrnoを示します。これらのシステムコールはread()やwrite()のシステムコールと同じエラーを生じる可能性があり、そのようなエラーを受け取った場合は、同じerrnoコードを示します。また、標準として、さらに2つのエラー状況が定義されています。
1つ目は、戻り型がssize_tのため、count iov_lenの全数値の合計がSSIZE_MAXより大きい場合はデータの移動は行われず、-1が戻され、errnoがEINVALとなります。
2つ目として、POSIXは、countがゼロより大きくIOV_MAX以下であることを要求します。IOV_MAX は
カウントの最適化
ベクター型I/Oの実行中、Linuxのカーネルは、各セグメントに相当するように内部データ構造を割り当てなくてはなりません。この割り当ては、通常、countの大きさに基づいて動的に発生します。しかし、最適化のために、Linuxのカーネルはスタック上にセグメントの小配列を生成します。そして、countが十分に小さい場合には、これを使用することでセグメントの動的な割り当てをネゲートし、その結果、性能を若干高める効果があります。現在の閾値(しきいち)は8です。したがって、countが8以下の場合、ベクター型I/Oは、カーネルスタックを使用する非常にメモリー効率の良い方法で実行されます。
特定のベクター型I/Oを実行するとき、一度に移動しなくてはならないセグメント数に関しては、 十中八九、選択の余地はないでしょう。しかし、小さい値を対象としている柔軟なユーザーであれば、8以下の値を選択することで、間違いなく効率がアップします。
writev( )例
ここで、3つのセグメントのベクターを書き出すシンプルな1例を考察してみましょう。各セグメントは大きさの異なる文字列を含んでいるとします。自給的なこのプログラムは、非常に完結性が高いのでwritev()を示すことができると同時に、非常にシンプルなので便利なコード・スニペットとして使うこともできます。以下のとおりです。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/uio.h>
int main ()
{
struct iovec iov[3];
ssize_t nr;
int fd, i;
char *buf[] = {
"The term buccaneer comes from the word boucan.\n",
"A boucan is a wooden frame used for cooking meat.\n",
"Buccaneer is the West Indies name for a pirate.\n" };
fd = open ("buccaneer.txt", O_WRONLY | O_CREAT | O_TRUNC);
if (fd == -1) {
perror ("open");
return 1;
}
/* fill out three iovec structures */
for (i = 0; i < 3; i++) {
iov[i].iov_base = buf[i];
iov[i].iov_len = strlen (buf[i]);
}
/* with a single call, write them all out */
nr = writev (fd, iov, 3);
if (nr == -1) {
perror ("writev");
return 1;
}
printf ("wrote %d bytes\n", nr);
if (close (fd)) {
perror ("close");
return 1;
}
return 0;
}
プログラムを実行すると、要求する結果が以下のように生成されます。
$ ./writev
wrote 148 bytes
ファイルの内容は、以下のとおりです。
$ cat buccaneer.txt
The term buccaneer comes from the word boucan.
A boucan is a wooden frame used for cooking meat.
Buccaneer is the West Indies name for a pirate.
(「buccaneer」という言い方は「boucan」という言葉に由来しています。
「boucan」とは、肉を調理するために使う木枠です。
西インド諸島では、海賊を「Buccaneer」と呼びます。)
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








