Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

ファイルディスクリプタについて(1)
~ファイルディスクリプタの概要

第1回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/01/29 14:00

 ファイルディスクリプタは、プログラムの外部との入出力を行う抽象的なインタフェースです。Unix/Linuxのファイルディスクリプタは、一般的なファイルだけでなくデバイスやソケットやパイプも対象としています。当連載は、ファイルディスクリプタの機能や管理方法などを提示します。第1回では、ファイルディスクリプタの概要を紹介します。

はじめに

 ファイルディスクリプタ(Windowsではファイルハンドル)は、プロセスや実行ファイルにとって外部の資源にアクセスしたりアクセスされたりする際に使用される抽象的なインターフェースです。

 今日のプログラムは必ずと言っていいほど外部とのインターフェースを持っていますが、新しいディスクリプタや効率的な使い方がそれほど明確ではなかったりします。

 当連載では、ファイルディスクリプタに関する調査・試行錯誤した結果、新しいディスクリプタを使用した感想や効率的な管理方法など、独断と偏見と誤解とたくさんのサンプルを記載します。

 今回使用している環境は、Fedora11とRedHatEL5.3を使用しています。主に連載の第4回まではFedoraを、それ以外ではRedHatEL5.3を使用しています。Fedoraのカーネルバージョンは2.6.29.4-167、glibcのバージョンは2.10.1-2です。Ubuntuの(現時点での)最新版9.04では、提供カーネルバージョンが2.6.28を採用しているらしいので、私は試していませんが、おそらく利用できると思います。RedHatは商用版なので、CentOSでも大丈夫でしょう。

連載概要

 この連載は、次のような内容について述べていく予定です。

連載目次

  • 第1回:ファイルディスクリプタの概要
  • 第2回:イベント用ディスクリプタ「eventfd」の特徴
  • 第3回:タイマー用ディスクリプタ「timerfd」の特徴
  • 第4回:シグナル用ディスクリプタ「signalfd」の特徴
  • 第5回:多重I/O「Multiplex I/O」の種類の特徴、使い方、性能差
  • 第6回:シグナル駆動I/Oの特徴、使い方
  • 第7回:非同期I/O「Asynchronous I/O」の使い方と性能差
  • 第8回:ファイルディスクリプタパッシングの特徴、使い方

 サンプルプログラムは100行前後程度までは画面に記載します。全プログラムは圧縮してページ上部よりダウンロード可能にします。makeコマンドでコンパイルできます。i386/x86_64環境で動作確認済みです。

 プログラムのボリューム上、エラー処理や引数チェックなどを省いているので、あらかじめご了解ください。また使用法を誤るとシステムに重大な影響を与える可能性があります。利用する場合は責任のとれる環境において実行するよう、お願いします。

 当トピックでは、実際にプログラムを通して動作確認や性能測定を行うことで、個人的な見解を述べさせていただきます。あくまで個人的な感想に基づいているので、反論や指摘などあるかと思います。指摘や質問などは大歓迎なので、その際はぜひご連絡ください。可能な限りの対応に努めます。

ファイルディスクリプタの概要

 ファイルディスクリプタはファイル操作を汎用的に行うために使用する整数値ですが、UNIX/Linuxではそれ以外も対象として操作できるよう、抽象的な作りになっています。

 ファイル操作用のファイルディスクリプタで有名なもので言うと、stdinstdiostderrが挙げられます。しかし、printf系の関数群に設定するstdinstdiostderrについて、これらはFILE構造体へのポインタであり、ファイルディスクリプタをラップしているので、本来のファイルディスクリプタと同じではありません。

 stdinstdiostderrに相当する実際のファイルディスクリプタの値は、それぞれ0、1、2になり、プログラムが実行時にこの3個のディスクリプタが開かれ、プログラム停止時に閉じられます。

 それ以外のファイルディスクリプタはプログラムで意識的に生成し責任を持って閉じる必要があります。主に下記の関数によってディスクリプタを生成します。

  • open(2)creat(2):ファイルおよびデバイスが対象
  • socket(2)socketpair(2)accept(2):ソケットが対象
  • pipe(2):パイプが対象

 上記の生成方法に沿って生成されたファイルディスクリプタは、read(2)およびwrite(2)の関数によって統一的に操作出来ます。

※注釈「creat」のスペルミスについて

 Unixの祖である、Ken Thompsonのスペルミスであることが、有力な説です。

 一方ではabbreviationではないかという意見もあるそうです。

新しいファイルディスクリプタについて

 今までのファイルディスクリプタは、ファイル・デバイス・ソケット・パイプを対象にしていました。しかし新たなカーネルとglibによって、今回、新たに3個のファイルディスクリプタが追加されました。

  • イベント(eventfd)
  • イベントの発生を待ったり通知したりする際に使用するファイルディスクリプタです。基本的な動作は名前なしパイプと同じです。親子プロセスやスレッド間で使用できます。

  • タイマー(timerfd)
  • 設定された時間がタイムアップしたことを通知するファイルディスクリプタです。

  • シグナル(signalfd)
  • シグナルが通知されたことを検知する為のファイルディスクリプタです。既存ではシグナルハンドラで実装されていましたが、ディスクリプタ経由で検知可能となりました。

まとめ

 今回は、ファイルディスクリプタの概要について解説しました。次回は、新たに追加された3個のファイルディスクリプタの中から、イベント用ファイルディスクリプタ「eventfd」を取り上げ、使用法や特徴、既存のファイルディスクリプタとの違いについて、説明していきたいと思います。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 赤松 エイト(エイト)

    (株)DTSに勤てます。 WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。 mixiもやってまして、こちらは子育てとか日々の日記メインです。

バックナンバー

連載:ファイルディスクリプタについて
All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5