c/c++: 进程间通信(匿名管道、有名管道、内存映射)

进程间通信的方式?

  • - 管道
    •     - 匿名管道
    •     - 有名管道
  •   - 内存映射
  •   - 本地套接字
  •   - 网络套接字
  •   - 消息队列
  •   - 共享内存

 

- 父子进程始终共享什么东西?

  •   - 文件描述符
  •   - 内存映射区

 

目录

一、管道

1.1匿名管道

创建匿名管道

匿名管道的原理:

实现过程:

匿名管道的局限性:

栗子:(使用匿名管道实现进程间通信)

2.2 有名管道

有名管道的原理:

创建方式:

创建栗子:(2个无关的进程通信)

二、内存映射

父子进程使用内存映射通信的栗子:

无关系进程使用内存映射通信的栗子:

三、总结

3.1 进程间通信

3.2 面试问题


 

一、管道

管道的本质:

  • 是内核缓冲区
  • 拥有文件的特质(读操作、写操作)
  • 匿名管道 -> 没有文件的实体
  • 有名管道 -> 有文件实体, 不存储数据
  • 可以文件操作的方式对管道进行处理

在创建子进程之前, 父进程通过文件操作打开了两个文件 a, b, 得到了两个文件描述符: fd3 fd4

父进程通过fork 创建子进程

子进程对应一个虚拟地址空间
    - 文件描述符表: fd3, fd4 -> 从父进程拷贝过来的
    - 在子进程中通过得到的fd3 fd4 来操作 A, B文件

 

1.1匿名管道

 

创建匿名管道

#include <unistd.h>
  int pipe(int pipefd[2]);  char* 
  	参数:
  		pipefd: 传出参数
  		- pipefd[0] -> 管道的读端
  		- pipefd[1] -> 管道的写端
  	返回值: 
  		0: 调用成功
  		-1: 失败

 

匿名管道的原理:

  • 没有名字, 在磁盘上没有实体, 是内存中的一块缓冲区
  • 这个缓冲区, 由父进程在fork()子进程之前创建得到的
  • 内核缓冲区有两部分
        - 读端 -> 可以进行读操作的文件描述符
        - 写端 -> 可以进行写操作的文件描述符
  • 父进程被销毁, 管道自动释放
  • 默认阻塞

匿名管道数据结构是一个环形队列,默认容量4k

 

实现过程:

  • - 读操作
    •     - 如果管道中有数据
      •       - read读, read返回值是读到的字节数
    •     - 管道中没有数据
      •       - 写端没有关闭, 但是写的慢,read会阻塞
      •       - 写端关闭了,read解除阻塞, 返回值为0

 

  •  - 写数据
    •     - 管道有空间。接着写, 写满之后阻塞
    •     - 没有空间。直接阻塞
  •     - 写数据的时候, 读端关闭了
    •       - 管道破裂
    •       - 进程被 SIGPIPE 信号杀死

 

管道的读写两端都默认阻塞,如何设置为非阻塞呢?

// 使用 fcntl 函数
// 设置读端为非阻塞  -> fd[0]
int flag = fcntl(fd[0], F_GETFL)
flag |= O_NONBLOCK;
fcntl(fd[0], F_SETFL, flag);

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值