设为首页 加入收藏

TOP

介绍一下IPC:interprocess communication 进程间通信(三)
2014-11-21 20:20:03 来源: 作者: 【 】 浏览:33
Tags:介绍 IPC interprocess communication 进程 通信
de);


f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));


f1->f_dentry = f2->f_dentry = dget(dentry);


f1->f_mapping = f2->f_mapping = inode->i_mapping;



/* read file */


f1->f_pos = f2->f_pos = 0; //为用于读的两个文件对象设置属性值


f1->f_flags = O_RDONLY; f_flage设置为只读,f_op设置为


f1->f_op = &read_pipe_fops; read_pipe_fops 结构的地址。


f1->f_mode = 1;


f1->f_version = 0;



/* write file */ //为用于写的两个文件对象设置属性值


f2->f_flags = O_WRONLY; f_flage设置为只写,f_op设置为


write_pipe_fops 结构的地址。


f2->f_op = &write_pipe_fops;


f2->f_mode = 2;


f2->f_version = 0;



fd_install(i, f1);


fd_install(j, f2);


fd[0] = i; //将两个文件描述符放入参数fd数组返回


fd[1] = j;


return 0;



close_f12_inode_i_j:


put_unused_fd(j);


close_f12_inode_i:


put_unused_fd(i);


close_f12_inode:


free_page((unsigned long) PIPE_BASE(*inode));


kfree(inode->i_pipe);


inode->i_pipe = NULL;


iput(inode);


close_f12:


put_filp(f2);


close_f1:


put_filp(f1);


no_files:


return error;


}



六、管道的释放


管道释放时f-op的release域在读管道和写管道中分别指向pipe_read_release()和pipe_write_release()。而这两个函数都调用release(),并决定是否释放pipe的内存页面或唤醒该管道等待队列的进程。


以下为管道释放的代码:


static int pipe_release(struct inode *inode, int decr, int decw)


{ down(PIPE_SEM(*inode));


PIPE_READERS(*inode) -= decr;


PIPE_WRITERS(*inode) -= decw;


if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {


struct pipe_inode_info *info = inode->i_pipe;


inode->i_pipe = NULL;


free_page((unsigned long) info->base);


kfree(info);


} else { wake_up_interruptible(PIPE_WAIT(*inode));


kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);


kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); }


up(PIPE_SEM(*inode));


return 0;}



七、管道的读写


1.从管道中读取数据:


如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;



当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。



2.向管道中写入数据:


向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞



八、管道的局限性


管道的主要局限性正体现在它的特点上:



只支持单向数据流;



只能用于具有亲缘关系的进程之间;



没有名字;



管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);



管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等。





九、后记



写完本文之后,发现有部分不足之处。在由于管道读写的代码过于冗长,限于篇幅不一一列出。有不足和错误之处还请各位老师指正。通过一段时间对Linux的内核代码的学习,开源的程序往往并非由“权威人士”、“享誉海内外的专家”所编写,它们的由一个个普通的程序员写就。但专业造就专家,长时间集中在某个领域中能够创建出据程序员应该珍视的财富





深刻理解Linux进程间通信(IPC)


一个大型的应用系统,往往需要众多进程协作,进程(Linux进程概念见附1)间通信的重要性显而易见。本系列文章阐述了Linux环境下的几种主要进程间通信手段,并针对每个通信手段关键技术环节给出详细实例。为达到阐明问题的目的,本文还对某些通信手段的内部实现机制进行了分析。




linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。Linux则把两者继承了下来,如图示:



其中,最初Unix IPC包括:管道、FIFO、信号;System V IPC包括:System V消息队列、System V信号灯、System V共享内存区;Posix IPC包括: Posix消息队列、Posix信号灯、Posix共享内存区。有两点需要简单说明一下:1)由于Unix版本的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix标准,这个新的ANSI Unix标准被称为计算机环境的可移植性操作系统界面(PSOIX)。现有大部分Unix和流行版本都是遵循POSIX标准的,而Linux从一开始就遵循POSIX标准;2)BSD并不是没有涉足单机内的进程间通信(socket本身就可以用于单机内的进程间通信)。事实上,很多Unix版本的单机IPC留有BSD的痕迹,如4.4BSD支持的匿名内存映射、4.3+BSD对可靠信号语义的实现等等。



图一给出了linux 所支持的各种IPC手段,在本文接下来的讨论中,为了避免概念上的混淆,在尽可能少提及Unix的各个

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

评论

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