FIFO


Rev.1を表示中。最新版はこちら

パイプはプロセス間でパイプinodeを共有することで、プロセス間の通信を可能としていました。通信するプロセス間ではこのinodeを持つファイル構造体を共有しています。従ってパイプで通信できるプロセスというのはこのファイル構造体を共有するプロセスグループ間での通信となるわけです。もし、プロセスグループ間を越えて通信する場合FIFOを使うことになります。FIFOは実ファイル上に作成した特殊ファイルを介してプロセス間の通信を行うものだからです。

実装はパイプの処理と同じで、パイプは静的に読み込み、書き込み2つのパイプを作成していますが、FIFOは作成時のopenのフラグで、読み込み用、書き込み用、読み書き用と指定することができることです。これはオープン時にそのモードに応じたパイプ用コールバックオペレーションをfile構造体に設定することで実現しています。またそれをうらずけるようにfile_operationsのdef_fifo_fopsには、.openコールバックしか定義されていません。

FIFOを作成すると、mknodにより、ファイルシステムに応じたmknodコールバック関数がよばれ、init_special_inode関数でそのinodeにfifoのファイルオペレーションdef_fifo_fopsが設定されます。この辺りの流れはデバイスファイル作成と同じです。

static int ext3_mknod (struct inode * dir, struct dentry *dentry,
                       int mode, dev_t rdev)
{

       inode = ext3_new_inode (handle, dir, mode);
       err = PTR_ERR(inode);
       if (!IS_ERR(inode)) {
               init_special_inode(inode, inode->i_mode, rdev);


void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
       inode->i_mode = mode;
       if (S_ISCHR(mode)) {
               inode->i_fop = &def_chr_fops;
               inode->i_rdev = rdev;
       } else if (S_ISBLK(mode)) {
               inode->i_fop = &def_blk_fops;
               inode->i_rdev = rdev;
       } else if (S_ISFIFO(mode))
               inode->i_fop = &def_fifo_fops;
       else if (S_ISSOCK(mode))
               inode->i_fop = &bad_sock_fops;
       else
               printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n",
                      mode);
}

const struct file_operations def_fifo_fops = {
       .open           = fifo_open,    /* will set read_ or write_pipefifo_fops */
};

FIFOがオープンされると、def_fifo_fopsで定義されているfifo_openがコールされます。fifo_openの最初の処理でまだパイプがなければ新規にpipe_inode_info構造体を取得し、inode->i_pipeに設定しています。その後ファイルオペレーションとして、openが読み込み用ならread_pipefifo_fops、書き込み用ならwrite_pipefifo_fops、読み書き用ならrdwr_pipefifo_fopsが設定され、以降の処理はパイプの処理として行っているようです。

static int fifo_open(struct inode *inode, struct file *filp)
{
       pipe = inode->i_pipe;
       if (!pipe) {
               ret = -ENOMEM;
               pipe = alloc_pipe_info(inode);
               if (!pipe)
                       goto err_nocleanup;
               inode->i_pipe = pipe;
       }

       switch (filp->f_mode) {
       case 1:
               filp->f_op = &read_pipefifo_fops;
   
       case 2:
               filp->f_op = &write_pipefifo_fops;
        
       case 3:
               filp->f_op = &rdwr_pipefifo_fops;

FIFOは実ファイル上の特殊ファイル介して通信を行っていると言っても、通信そのものはパイプです。パフォーマンス的にはパイプと同等と言えそうです。


最終更新 2010/02/28 22:56:44 - north
(2010/02/28 22:56:44 作成)


検索

アクセス数
3689596
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。