进程间通信(管道、共享内存、消息队列、信号量)—Linux系统编程

进程间通信

管道(数据传输)、共享内存(数据共享)、消息队列(数据传输)、信号量(进程控制)

为什么需要进程间通信?

  • 每一个进程都是拥有自己的独立的虚拟地址空间和页表结构,促使了进程独立,导致了进程和进程之间相互协作的问题,为了解决这种问题,才产生了进程间通信。

进程间通信种类的细分:

  • 数据传输
  • 数据共享
  • 进程控制

管道(pipe)

匿名管道

  • 我们把从一个进程连接到另一个进程的数据流称为一个管道;
  • 需要通信的两个进程在管道的两端;
  • 匿名管道就是内核当中的一块缓存;

特性

  • 只能用于有亲缘关系的进程之间进行通信

  • 是半双工的,数据只能在一个方向流动(从写端到读端)

  • 提供字节流式服务 ——如果读端没有及时进行读的话,但是写端往进去写了,后面写的数据会追加在之前写的数据后面。数据其实都是二进制存储的,没有明确的数据边界,如果两次的数据表达的内容是不同的内容,有可能导致读端获取到数据之后,无法知道写端表达的是什么意思。

  • 读端读数据的时候,是从管道当中将数据拿走了,并不是当前被读走的数据还存留在管道中。

  • 生命周期随进程——进程退出,管道释放

  • 内核会对管道操作进行同步和互斥

    • 临界资源:同一时间,当前的资源只能被一个进程所访问,由于不同的进程对临界资源访问的时候,不会
    • 同步:同一时间,保证只能有一个进程访问资源
    • 互斥:保证对临界资源访问的合理性
  • PIPE_SIZE:65536字节,64K(匿名管道的大小) PIPE_BUF:4K大小 ——保证写入数据或读取数据的原子性

    • 原子性:当前的操作不能被打断,运行的结果只能有两个,要么是操作完成(1),要么是操作没有完成(0)

创建

pipe()会建立管道,并将文件描述符由参数filedes数组返回

#include <unistd.h>
int pipe(int filedes[2])
  • filedes[2]是一个出参,也就是我们在使用该函数的时候,需要传入一个int类型大小为2的数组,在函数内部会将数组的值进行补充,调用完成后之后,就能拿到管道对应的读写端;数组中的每一个元素都是一个文件描述符
  • filedes[0]为管道里的读取端,filedes[1]为管道里的写入端
  • 返回值:若成功返回0,否则返回-1,错误原因存在errno中

父子进程通信

  1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
  2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。

读写规则

  • 读管道
    • 管道中有数据,read返回实际读到的字节数
    • 管道中无数据:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值