进程间的通讯--管道(有名、无名)

进程间的通讯–管道(有名、无名)

管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。(无名管道)

【命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。】

管道

1、特点:

  • 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

  • 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)无名管道只适用于父子进程间通信,有名管道可以再任何进程之间通讯

  • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

  • 管道分为pipe(无名管道)和fifo(命名管道)两种,除了建立、打开、删除的方式不同外,这两种管道几乎是一样的。他们都是通过内核缓冲区实现数据传输。

pipe用于父进程和子进程之间的通讯,它通过pipe()系统调用来创建并打开,当最后一个使用它的进程关闭对他的引用时,pipe将自动撤销。

FIFO即命名管道,在磁盘上有对应的节点,但没有数据块——换言之,只是拥有一个名字和相应的访问权限,通过mknode()系统调用或者mkfifo()函数来建立的。一旦建立,任何进程都可以通过文件名将其打开和进行读写,而不局限于父子进程,当然前提是进程对FIFO有适当的访问权。当不再被进程使用时,FIFO在内存中释放,但磁盘节点仍然存在。

管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次,读出以后再缓冲区都不复存在了。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或写进程是否进入等待队列,当空的缓冲区有新数据写入或慢的缓冲区有数据读出时,就唤醒等待队列中的进程继续读写

在这里插入图片描述
无名管道: 父进程创建管道,并在管道中写入数据,而子进程从管道读出数据

仅仅适用于具有亲缘关系(如父子进程)的进程间通信,因为匿名管道无法被其他进程找到,也就无法通信,所以只能通过子进程复制父进程的方法,让子进程能够访问到相同的管道来实现通信。(管道的操作:io操作------文件描述符)

特点:

  1、使用条件:只能用于具有亲缘关系(父子进程,兄弟进程等)的进程之间的通信

  2、通信模式:半双工模式,fd[0]作为读端,fd[1]作为写端

  3、读写方式:对于它的读写采用文件IO(不支持lseek函数)

  4、读操作会阻塞(等待):在管道中无数据情况下。
     写操作会阻塞(等待):当管道被写满时,无名管道的大小为64K
     如果所有管道写入端关闭,read读完所有数据之后返回0;
     如果所有管道读取端关闭,write将触发异常,操作系统此时会发送SIGPIPE信号,
     通知我们读取端都被关闭了。(这个信号会导致write端进程退出)5、管道破裂:管道读端关闭,再向管道中写数据时。

注意: 接口:pipe(int fd[2]),其中fd[1]用于读,fd[2]用于写。创建匿名管道必须在创建子进程之前,否则子进程将无法复制。
在这里插入图片描述
在这里插入图片描述
有名管道:
和无名管道的主要区别在于,命名管道有一个名字,命名管道的名字对应于一个磁盘索引节点,有了这个文件名,任何进程有相应的权限都可以对它进行访问。

- 创建:mkfifo

- 读写特性:与匿名管道相同。

- 匿名管道是已经直接打开了,pipe接口直接返回的文件描述符,命名管道创建之后并不会直接打开,需要我们用户自己open打开来进行后续操作。

- 如果没有一方以写的方式打开,那么以读的方式打开时就会阻塞;

- 如果没有一方以读的方式打开,那么以写的方式打开时就会阻塞。

-  如果以读写方式打开,则不会阻塞

注意:FIFO不同于无名管道之处在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据。值的注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
在这里插入图片描述
mainA.c 读端:
在这里插入图片描述
mainB.c 写端:
在这里插入图片描述
执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值