几种跨进程通信的机制

概述

由于不同的进程在运行过程中处于不同的用户空间,无法相互感知,因此就诞生 IPC;信息的传播需要介质,几种跨进程通信的机制就是使用了不同的介质,由于介质的不同,所以传输的方式,传输的频率、传输的数据和适用范围都有不同;

文件

放在物理磁盘上的文件作为不同进程都能访问到的东西,可以作为介质;

优点:

  1. 操作简单

缺点:

  1. 通信效率太低

内存

使用文件作为IPC介质,效率实在太低,太多时间耗费在 IO 上;因此可以选用内存作为传输介质;

管道

虽然操作一个在磁盘上的文件很慢,但是操作一个在内存里的文件很快;
管道就是一个在内存里的文件,它在内核空间里开辟了一段内存,然后把对这段内存的读写封装为文件操作,既保留了文件操作的简单性,又保留了内存访问的快速;

当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。
当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。
当两个进程都终结的时候,管道也自动消失。

优点:

  1. 操作简单,读写快速;

缺点:

  1. 缺少同步机制,读写无法互斥;
  2. 传输数据有大小限制;
  3. 一次读写发生四次拷贝,系统调用过多;

消息队列

顾名思义,消息队列 就是要传输的信息以特定格式封装为消息,然后以链表的方式存放在内核空间;
消息格式:

struct msgbuf{
	long mtype;//消息类型(>0)
	char mtext[128];//消息文本
};

优点:

  1. 消息内容独立于进程,进程消失,消息队列的内容也不会删除;
  2. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按照消息的类型读取;
  3. 我们可以通过发送消息来几乎完全避免命名管道的同步和阻塞问题;

缺点:

  1. 消息内容有长度限制;
  2. 消息队列的长度也有限制;
  3. 一次读写发生四次拷贝,系统调用过多;

共享内存

上面所说的管道和消息队列各有优劣,但是都有一个同样的缺点:一次读写发生四次拷贝,系统调用过多;
这是由于数据需要从用户态转移到内核态,额外发生了一次拷贝;针对这样的高效场景,共享内存 通过把两个进程的一段内存空间映射到同一段物理内存;

网络

UNIX Domain Socket

Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信。socket 原本是为网络通讯设计的,但后来在 socket 的框架上发展出一种 IPC 机制,就是 UNIX domain socket。虽然网络 socket 也可用于同一台主机的进程间通讯(通过 loopback 地址 127.0.0.1),但是 UNIX domain socket 用于 IPC 更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC 机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。
UNIX domain socket 是全双工的,API 接口语义丰富,相比其它 IPC 机制有明显的优越性,目前已成为使用最广泛的 IPC 机制,比如 X Window 服务器和 GUI 程序之间就是通过 UNIX domain socket 通讯的。
Unix domain socket 是 POSIX 标准中的一个组件,所以不要被名字迷惑,linux 系统也是支持它的。

Network Socket

UNIX Domain Socket 类似,但是它是以 TCP/IP 协议为基础的;

RPC

Remote Procedure Call 远程过程调用,有以下几个特点:

  1. 屏蔽了网络调用的具体细节,调用远程方法对于开发者来说就像是调用本地方法一样;
  2. 使用自定义的 TCP 协议,可以让请求报文体积更小,或者使用 HTTP2 协议,也可以很好的减少报文的体积,提高传输效率。
  3. RPC 实现需要实现编码,序列化,网络传输等。
posted @ 2023-06-07 12:11  ijkzen  阅读(143)  评论(0编辑  收藏  举报