设为首页 加入收藏

TOP

介绍一下IPC:interprocess communication 进程间通信(二)
2014-11-21 20:20:03 来源: 作者: 【 】 浏览:34
Tags:介绍 IPC interprocess communication 进程 通信
进程控制块),描述进程所占用的资源,这样,进程才能接受内核的调度;


具有独立的存储空间


进程和线程有时候并不完全区分,而往往根据上下文理解其含义。



Linux环境进程间通信 ——无名管道工作机制研究



一、引言


Linux作为一个开源的操作系统,是我们进行操作系统和提高编程水平的最佳途径之一。



好的程序如同好的音乐一样,完成的完美、巧妙。开放源码的程序都是经过无数人检验地,本文将以linux-kernel-2.6.5为例对pipe的工作机制进行阐述。




二、进程间通信的分类


大型程序大多会涉及到某种形式的进程间通信,一个较大型的应用程序设计成可以相互通信的“碎片”,从而就把一个任务分到多个进程中去。进程间通信的方法有三种方式:



管道(pipe)



套接字(socket)



System v IPC 机制



管道机制在UNIX开发的早期就已经提供了,它在本机上的两个进程间的数据传递表现的相当出色;套接字是在BSD(Berkeley Software Development)中出现的,现在的应用也相当的广泛;而System V IPC机制Unix System V 版本中出现的。





三、工作机制



管道分为pipe(无名管道)和FIFO( 命名管道),它们都是通过内核缓冲区按先进先出的方式数据传输,管道一端顺序地写入数据,另一端顺序地读入数据读写的位置都是自动增加,数据只读一次,之后就被释放。在缓冲区写满时,则由相应的规则控制读写进程进入等待队列,当空的缓冲区有写入数据或满的缓冲区有数据读出时,就唤醒等待队列中的写进程继续读写。




管道的读写规则:



管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。一般文件的I/O函数都可以用于管道,如close、read、write等等



四、pipe的数据结构


首先要定义一个文件系统类型:pipe_fs_type。



fs/pipe.c


static struct file_system_type pipe_fs_type = {


.name = “pipefs”,


.get_sb = pipefs_get_sb,


.kill_sb = kill_anon_super,


};


变量pipe_fs_type其类型是 struct file_system_type 用于向系统注册文件系统。


Pipe以类似文件的方式与进程交互,但在磁盘上无对应节点,因此效率较高。Pipe主要包括一个inode和两个file结构——分别用于读和写。Pipe的缓冲区首地址就存放在inode的i_pipe域指向pipe_inode_info结构中。但是要注意pipe的inode并没有磁盘上的映象,只在内存中交换数据。



static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,


int flags, const char *dev_name, void *data)


{


return get_sb_pseudo(fs_type, “pipe:”, NULL, PIPEFS_MAGIC);


}


上为超级的生成函数。


Include/linux/pipe.h


#ifndef _LINUX_PIPE_FS_I_H


#define _LINUX_PIPE_FS_I_H



#define PIPEFS_MAGIC 0×50495045


struct pipe_inode_info {



wait_queue_head_t wait; 1



char *base; 2



unsigned int len; 3


unsigned int start; 4


unsigned int readers; 5


unsigned int writers; 6


unsigned int waiting_writers; 7


unsigned int r_counter; 8


unsigned int w_counter; 9


struct fasync_struct *fasync_readers; 10



struct fasync_struct *fasync_writers; 11



};


2 管道等待队列指针wait


3 内核缓冲区基地址base


4 缓冲区当前数据量


6 管道的读者数据量


7 管道的写者数据量


8 等待队列的读者个数


9 等待队列的写者个数


11、12 主要对 FIFO



五、管道的创建:


通过pipe系统调用来创建管道。


int do_pipe(int *fd)


{


struct qstr this;


char name[32];


struct dentry *dentry;


struct inode * inode;


struct file *f1, *f2;


int error;


int i,j;



error = -ENFILE;


f1 = get_empty_filp(); //分配文件对象,得到文件对象指针用于读管道


if (!f1)


goto no_files;



f2 = get_empty_filp(); //分配文件对象,得到文件对象指针用于读管道


if (!f2)


goto close_f1;



inode = get_pipe_inode(); //调用get_pipe_inode获得管道类型的索引节点


if (!inode) 的指针inode。


goto close_f12;



error = get_unused_fd(); //获得当前进程的两个文件描述符。在当前的


if (error < 0) 进程的进程描述符file域中,有一个fd 域,


goto close_f12_inode; //指向该进程当前打开文件指针数组,数组


i=error; 元素是指向文件对象的指针。



error = get_unused_fd();


if (error < 0)


goto close_f12_inode_i;


j = error;





error = -ENOMEM;


sprintf(name, “[%lu]“, inode->i_ino); //生成对象目录dentry,


this.name = name; 并通过它将上述两个文


this.len = strlen(name); 件对象将的指针与管道


this.hash = inode->i_ino; /* will go */ 索引节点连接起来。


dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);


if (!dentry)


goto close_f12_inode_i_j;


dentry->d_op = &pipefs_dentry_operations;


d_add(dentry, ino

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇最新远光软件笔试题面试题内容(4) 下一篇拿到腾讯实习offer后,有些话我想说

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: