进程间通信的6中通信方式

进程间通信的6中通信方式

一、管道通信

匿名管道:

  • 应用场景:
    Linux的 | 命令就是管道,将前一个命令的输出作为后一个命令的输入。
  • 管道的特点:
    单向传输数据,如果需要双向传输需要创建两个管道。
  • 缺点:管道的通信方式效率低,不适合进程间频繁地交换数据。大小收到限制,只能在父子进程间通信
  • 优点: 简单,同时可以很容易知道管道里的数据已经被另一个进程读取了。
  • 实现原理:
    就是在内核空间里开辟的一块缓存区域,并返回两个文件描述符fd[2]。
  • 如何实现进程间通信:
    因为管道是匿名的管道,所以两个文件描述符都在一个进程中,只能通过进程的继承关系,继承父进程的文件描述符。这样两个进程就都各有两个【fd[0]和fd[1]】,两个进程就可以通过各自的fd读写同一个管道文件实现进程通信。

命名管道:

  • 与匿名管道的区别:
    主要是匿名管道提前创建了一个管道文件,并给文件描述符赋予了名字,之后各个进程就可以通过名字获取到管道的文件描述符,这样就实现的不是父子进程也可以进行通信。

二、消息队列

  • 实现原理:保存在内核中的消息链表中,发送数据会把数据分为数据单元,称为消息体。
  • 缺点:
    通信不及时,消息体的大小有限制,消息队列的长度也有限制。存在用户态到内核态的切换和数据拷贝的开销。
  • 优点:解决的管道通信方式的效率低。
  • 应用场景:
    根据上面的优缺点,可以联想到到消息队列适用于进程间通信频繁的通信,保证一个进程发送完消息可以立即返回做其他事情。由于消息体和消息队列的大小和长度限制,消息队列不适合比较大的数据传输场景。

三、共享内存

现代的操作系统对内存的管理采用的是虚拟内存管理,每个系统都有自己独立的虚拟内存空间,而且进程的虚拟地址是一样的,但是虚拟内存映射的物理内存地址是不一样,这样进程的各自操作都互不影响。

  • 实现原理:进程各自拿出一块自己的虚拟地址空间,都映射到相同的物理内存中。
  • 优点:避免的数据频繁拷贝的问题, 也解决的消息队列中用户态和内核态之间切换和拷贝问题。
  • 缺点:由于是共享资源,就会涉及到资源同步和互斥问题。

四、信号量

目的: 就是解决共享内存的同步和互斥问题,为共享内存提供一套保护机制。

原理: PV操作

五、信号

信号是进程间通信机制中唯一的异步通信机制,一旦有信号产生,用户进程对信号的处理方式有:
- 执行默认操作。
- 捕捉信号。
- 忽略信号

作用:信号可以在应用进程和内核之间直接交互,内核也可以用信号来通知用户空间的进程发生哪些系统实践。

六、Socket

跨网路与不同主机上的进程之间通信,也可以在同主机上进程间通信。
根据Socket的类型不同,分为三种常见的通信方式:

  • 基于TCP协议的字节流通信
  • 基于UDP协议的数据报通信方式
  • 本地进程间通信方式。

线程间通信

因为进程中的各个线程是共享进程的资源的,所以只要是共享的变量,线程都可以访问到。在线程间更加关注的是互斥和同步的问题。