进程间通信之管道

什么是进程间通信?

  • 进程间通信就是操作系统为用户所提供的进程间几种通信方式

操作系统为什么要为用户提供进程间通信方式?

  • 因为进程的独立性(都操作的是自己虚拟地址空间中的虚拟地址,无法访问别人的地址),因此无法直接通信,因此需要操作系统给用户提供一些公共的媒介让多个进程都能通过访问这个媒介进行通信。
    但是也因为进程间的通信场景有多种,因此操作系统提供了多样的通信方式
    system V标准:
    管道、共享内存、消息队列、信号量

管道

  • 管道:是一种半双工通信方式——传输数据资源,本质是操作系统在内核中创建一块缓冲区 (多个进程只要都能访问到这个缓冲区就可以实现通信了)
  • 管道分类:匿名管道和命名管道
匿名管道
  • 匿名管道:从名字上看就是没有名字的管道,它是一块内核中没有名字的缓冲区。
    一个进程通过系统调用接口,在内核中创建的一块没有明确标识的缓冲区;内核返回两个文件符供进程来操作管道,其中一个描述符用于从管道读取数据;一个向管道中可以写入数据
    但是因为匿名管道没有明确标识,意味着其他进程无法找到缓冲区,无法进行通信;因此匿名管道只能用于具有亲缘关系的进程间通信,因为子进程可以通过复制父进程pcb中的文件描述符信息,得到管道的操作句柄
匿名管道的创建
  • int pipe(pipefd[2]);
    • pipefd : 至少具有两个int型元素的数组。创建一个管道,通过pipefd获取系统返回的管道操作句柄,其中pipefd[0]用于从管道读取数据,pipefd[1]用于向管道写入数据。
    • 返回值:0 失败:-1
      在这里插入图片描述
匿名管道的读写特性
  • 1、若管道中没有数据,则read会阻塞,直到数据被写入(缓冲区中有数据)
  • 2、若管道中数据满了,则write会阻塞,直到数据被读取(缓冲区有空闲空间)
  • 3、若管道的所有读端被关闭,则write会触发异常进程退出
  • 4、若管道所有写端被关闭,则read会返回0
命名管道
  • 命名管道:命名管道可以用于同一主机上的任意进程间通信
    命名管道在内核中这块缓冲区是有标识的,意味着所有的进程都可以通过这个标识找到这块缓冲区实现通信。命名管道的标识实际上是一个文件,可见于文件系统,意味着所有进程都可以通过打开文件进而访问到内核中的缓冲区
命名管道的创建
  • int mkfifo(const char *pathname, mode_t mode);
    • pathname : 管道文件名称
    • mode:管道文件权限
    • 返回值:0 失败: -1
      在这里插入图片描述
      接下来看一下命名管道的打开特性
  • 我们首先以只读的方式打开,看会出现什么情况
    在这里插入图片描述
    在这里插入图片描述
    从图上看到程序没退出,也没打印那一段话。那么接着我们再以只写的方式打开看看会出现什么情况?
    在这里插入图片描述

我们会发现以只写的方式打开跟以只读的方式打开结果一样,程序既没退出,也没打印我们要的结果。接下来我们分析以下命名管道的打开特性

  • 命名管道的打开特性:
    若文件当前没有已经被已读的方式打开,则以O_WRONLY打开时会阻塞
    若文件当前没有已经被以写的方式打开,则以O_RDONLY打开时会阻塞
从上面的匿名管道和命名管道中我们总结一下管道的特性
  • 管道特性:
    1、管道是半双工通信
    2、管道的读写特性 + (命名管道的打开特性)
    3、管道的生命周期随进程(所有管道的操作句柄被关闭)
    4、管道自带同步与互斥(管道的读写数据大小在不超过PIPE_BUF-4096时保证操作的原子性)
    5、管道提供字节流服务
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值