进程间通讯

  • 管道(内核管理的一个缓冲区)

    • 匿名管道:通常用于父子进程的通信(通过fork复制父进程的信息,关闭父进程的读(或写)通道和子进程的写(或读)通道从而形成单向通信的通道)
    • 有名管道:通常用于无亲缘关系进程间的通信
    • 四种读写情况
      • 读端不读(fd[0]未关闭),写端一直写 :直到管道写满数据后,再次write会导致阻塞,直到管道有空位置才写去数据并返回
      • 写端不写(fd[1]未关闭),但是读端一直读(写端不关闭):管道为空时阻塞读端,直到管道有数据时才读数据并返回(是否阻塞取决于写端计数器是否大于0….)
      • 读端一直读,且fd[0]保持打开,而写端写了一部分数据不写了,并且关闭fd[1]:读取管道所有数据后返回0
      • 读端读了一部分数据,不读了且关闭fd[0],写端一直在写且f[1]还保持打开状态:一旦读端关闭而进程write时会接受信号SIGPIPE,通常导致进程异常终止
    • 局限性
      • 只支持单向数据流
      • 缓冲区有限,管道只存在于主存中
      • 所传送的是无格式字节流
      • 效率低下(写数据需要读端读取后才返回)
      • 需要注意同步问题?(自带有同步机制)
      • 有名管道:长期存于系统中,使用不当容易出错
  • 消息队列

    • 实际上就是信息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    • 信息的传递经过四次信息复制:写端->内核 内核->读端(消息队列中信息的复制需要额外消耗CPU的时间.不适宜于信息量大或操作频繁的场合)
    • 消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点
    • 可以实现任意进程间的通信,并通过系统调用函数来实现消息发送和接收之间的同步,无需考虑同步问题,方便
  • 共享内存

    • 内存共享机制:将进程的虚拟地址空间映射到相同的物理内存中
    • 该做法会引起进程的内存竞争问题
    • 共享内存是最快的IPC(进程间通信)方式
  • 信号量

    • 用于实现进程间的互斥同步问题
  • socket

    • 不同主机间进程通信的主要方法