linux 进程间通信 学习记录 三

进程间通信

常见IPC方法

管道:使用简单

FIFO:非血缘关键间

信号:开销小

共享内存:非血缘关系间

本地套接字:稳定性好

管道

特性

  • 伪文件(内核缓冲区)
  • 两个文件描述符(r/w)
  • 数据从写端流入,读端流出

原理

  • 内核缓冲区
  • 环形队列

局限性

  • 进程自己写不能自己读
  • 数据不能反复读
  • 单向通信(半双工)
  • 只能用于有公共祖先的进程间

pipe函数

  • 参数

  • 返回值

    • 成功:0

    • 失败:

      • -1
      • errno

管道读写行为

  • 读管道

    • 管道中有数据

      • read返回实际读到的字节数
    • 管道中无数据

      • 写端全关闭:read返回0
      • 仍有写端打开:阻塞等待
  • 写管道

    • 读端全关闭

      • 进程异常终止(SIGPIPE信号)
    • 有读端打开

      • 管道未满:写数据,返回写入字节数
      • 管道已满:阻塞(少见)
  • 父子进程间通信 ls | wc -l

  • 兄弟进程间通信

获取管道缓冲区大小

  • 命令:ulimit -a
  • 函数: fpathconf 参2:__PC_PIPE_BUF

管道优劣

  • 优点:实现手段简单

  • 缺点:

    • 单向通信
    • 只能有血缘关系进程间使用

FIFO

命名管道(Linux基础文件类型)

创建

  • 命令:mkfifo

  • 函数:mkfifo

    • 参数:

      • name
      • mode:8进制
    • 返回值:

      • 成功:0
      • 失败:-1,设置errno

无血缘关系进程间通信

  • 使用同一FIFO
  • 可多读端,多写端

共享存储映射

文件实现进程间通信

  • fork后父子进程共享文件描述符
  • 无血缘关系进程打开同一文件

存储映射I/O

  • 借助文件创建映射内存

  • mmap函数

    • 参数:

      • addr: 建立映射区的首地址 (NULL内核自动分配)

      • length: 欲创建映射区的大小

      • prot:

        • PROT_READ
        • PROT_WRITE
        • PROT_READ|PROT_WRITE
      • flags:

        • MAP_SHARED
        • MAP_PRIVATE
        • MAP_ANONYMOUS/MAP_ANON
      • fd: 文件描述符

      • offset:映射偏移(4K整数倍)

    • 返回值:

      • 成功:

        • 映射区首地址
      • 失败:

        • MAP_FAILED
        • 设置errno
  • munmap函数

    • 参数:

      • mmap返回值
      • 映射区大小
    • 返回值:

      • 成功:

        • 0
      • 失败:

        • -1
        • 设置errno
  • 使用注意事项:

      1. 映射区建立过程中隐含一次读操作
      1. MAP_SHARED时 映射区权限<=打开文件权限
      1. 映射区建立成功,文件即可关闭。
      1. 大小为0的文件无法创建映射区
      1. munmap参数应与mmap返回值严格对应
      1. 偏移位置必须为4k整数倍
      1. mmap返回值判断不能省略

父子进程间mmap通信

  • flags:

    • MAP_PRIVATE: 独占映射区
    • MAP_SHARED: 共享映射区
  • 父子共享

    • 打开文件描述符
    • mmap建立的映射区(MAP_SHARED)

匿名映射

  • Linux

    • length:

      • 任意
    • flags:

      • MAP_ANONYMOUS
      • MAP_ANON
    • fd:

      • -1
  • 类Unix

    • length:

      • 任意
    • fd:

      • open(/dev/zero, O_RDWR)

无血缘关系进程间mmap通信

  • 使用同一文件创建映射区
  • 指定MAP_SHARED
  • 可多读端,多写端

基本概念 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信

以下几个最重要
① 管道 (使用最简单)
② 信号 (开销最小)
③ 共享映射区 (无血缘关系)
④ 本地套接字 (最稳定)

管道的优劣
优点:简单,相比信号,套接字实现进程间通信,简单很多。
缺点:1. 只能单向通信,双向通信需建立两个管道。
2. 只能用于父子、兄弟进程(有共同祖先)间通信。该问题后来使用fifo有名管道解决。

1. 其本质是一个伪文件(实为内核缓冲区) 
  1. 由两个文件描述符引用,一个表示读端,一个表示写端。
    1. 规定数据从管道的写端流入管道,从读端流出。
      管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
      管道的局限性:
      ① 数据自己读不能自己写。
      ② 数据一旦被读走,便不在管道中存在,不可反复读取。
      ③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
      ④ 只能在有公共祖先的进程间使用管道。

三个作业 坐一下

本地简易聊天室 qq
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值