Linux操作系统中的管道(pipe)使用方法

来源:互联网 发布:tc编程 编辑:程序博客网 时间:2024/06/05 00:40
前面在一段小程序中看到了mkfifo这样的一个函数,在baidu了一下之后对于进程间通信产生了一点兴趣,所以就小小的研究了一下。
在一个多进程操作系统所提供的运行环境下,可以通过两种不同的途径或者说采用两种不同的策略,来建立起复杂的大型应用系统。一种途径就是通过一个孤立的,大型的,复杂的进程提供所需的全部服务,另外一种途径就是通过由若干相互联系的,小型的。相对简单的进程构成的组合来提供所需的功能。早期的操作系统往往倾向与前者,而Unix以及其衍生的各种操作系统往往倾向于后者。相比之下,后者有着各种好处:1.模块化,2.各个进程都得到保护,在相当程度上排除了相互干扰的可能性,3.灵活性更强。
当然这种好处也是要付出代价的,也有缺点,但是相比之下,这种途径的优点远远超出了其缺点。
Unix(从而Linux)向应用软件提供了一些进程间通信的手段,早期的Unix提供了:管道(pipe),信号(signal),跟踪(trace)。
这里我们只谈管道:父进程与子进程,或者两个兄弟进程之间,可以通过系统调用建立起一个单向的通信管道。但是,这种管道只能由父进程来建立,所以对于子进程来说是静态的,与生俱来的。管道两端的进程各自将该管道视作一个文件。一个进程往通道中写的内容由另一个进程从通道读出,通过通道传递的内容遵循“先入先出”(FIFO)的规则。每个通道都是单向的,需要双向通信时要建立起两个通道。
下面说一说进程间管道的建立,在这之前我们要说到fork()函数,在Linux系统中一个新的进程是由一个已经存在的进程“复制”出来的,而不是“创造”出来的(而所谓的“创建”实际上就是复制)。
管道机制的主体是系统调用pipe(),但是由pipe()所建立的管道的两端都在同一个进程中,这样的管道起不到进程间通信的作用。所以必须在fork()的配合下,才能在父子进程间或者两个子进程之间建立起进程间的通信管道。
下面就介绍一下怎样将管道用于进程间通信:
(1)进程A创建了一个管道,创建完成时代表管道两端的两个已打开文件都在进程A中。

(2)进程A通过frok()创建出进程B,在fork()的过程中进程A的打开文件表按原样复制到进程B中。

(3)进程A关闭管道的读端,而进程B关闭管道的写段。于是,管道的写段在进程A中而读端在进程B中,成为了父子进程之间的通信管道。

(4)进程A又通过frok()创建进程C,而后关闭其管道写段而与管道脱离关系,使得管道的写段在进程C中而读端在进程B中,成为两个兄弟进程之间的管道。

人们在认识到管道机制也存在一些缺点和不足。由于管道是一种“无名”,“无形”的文件,它可以通过fork()的过程创建于“近亲” 的进程之间,而不能成为可以在任意两个进程之间建立通信的机制,更不可能成为一种一般的,通用的进程间通信模型,同时,管道机制的这种缺点本身强烈的暗示着人们,只要用“有名”,“有形”的文件来实现管道,就能克服这种缺点。所以有了管道之后,“命名管道”的出现时必然的。
为了实现“命名管道”,在“普通文件”,“块设备文件”,“字符设备文件”之外,又设立了一种文件类型,称为FIFO文件。对这种文件的访问严格遵循“先进先出”的原则。这样就可以像在磁盘上建立一个文件一样建立一个命名管道,具体可以使用命令mknod来建立。例如:
% mknod mypipe   p
这里的参数“p”表示所建立的节点的类型。
我们从——help中可以看出:
  b      create a block (buffered) special file
  c, u   create a character (unbuffered) special file
  p      create a FIFO
至于管道的具体使用,大家可以连接下面的一个网址
http://blog.163.com/zqs1111/blog/static/37203887200946344191
原创粉丝点击