TEDIA会員に登録したメールアドレスとパスワードを入力してください

メールアドレス:

     パスワード:


パスワードを忘れた方はパスワードの確認を行ってください。

TEDIA会員へのご登録がお済みで無い方はこちらで登録ができます


>> テクノロジーポータル TEDIA トップページへ戻る <<

Think IT Software Developer's Think IT Find-IT 失敗しないソフト選び Find-IT TEDIA テクノロジーポータル TEDIA インストールマニアックス2008 インストールマニアックス2008

TEDIA SponsorsOpen 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 はに定義されています。Linuxの場合、現在、IOV_MAXは1024です。Countがゼロのとき、システムコールは0を戻します。* countがIOV_MAXより大きい場合はデータの移動は行われず、-1が戻され、errnoがEINVALとなります。

カウントの最適化

 ベクター型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」と呼びます。)


前のページ     1    2    3    4    次のページ

Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.