Interprocess Communication (IPC)
背景概述
通信目的
- 数据并行化以实现计算加速
Data Parallelization for Computational Speedup.
- 在应用程序中对功能或微服务进行模块化、流水线或分层划分
Modular, Pipelined or Layered Division of functions or microservices within an application.
- 为了在客户端使用网络服务
Client use of a service on a network.
通信问题
Design Issues for IPC
可靠性
Reliability
在消息传递过程中,可能会出现消息丢失或乱序 (lost and scrambled messages)。
因此需要具备相应的机制来确保消息的可靠传递 (ensure message sequences arrive correctly),比如使用:
- 序列号 (sequence number):发送方给每个数据包分配一个唯一的序列号,接收方可以通过序列号对数据包进行排序和重组。序列号还可以用于检测丢失的数据包和重复的数据包。
- 超时/应答/重传 (timeouts/acks/retrans mission):发送方发送数据包后,会设置一个超时时间。如果在超时时间内没有收到接收方的确认 (ACK),则认为该数据包可能丢失,发送方会重新发送该数据包。
安全性
Security
在公共网络上,通常希望对消息进行编码 (Encryption),以便只有通信双方能够阅读其内容。
SSL (Secure Sockets Layer) 和 IPSec (Internet Protocol Security) 是常用的加密协议,它们提供了安全的通信通道。
同步性
Synchronisation
- 阻塞发送
Blocking Send,发送进程在执行发送操作时会被阻塞,直到将消息传递给接收进程。
- 阻塞接收
Blocking Receive,接收进程在执行接收操作时会被阻塞,直到接收到一条有效的消息。
- 非阻塞发送
Non-Blocking Send,发送进程发送一条消息后,继续执行其他任务,消息在后台传递。
- 非阻塞接收
Blocking Receive,接收进程执行接收操作时会立即返回,无论是否有可用的消息。
如果有可用消息,则接收进程获取消息;否则,接收操作返回一个特定的空值。
缓冲方式
Buffering,进程通信可能涉及大量的数据传输,需要考虑如何合理地进行数据缓冲和流量控制,以避免数据的积压或拥塞问题。
它是实现非阻塞的必要条件,允许发送方在消息传递过程中不受接收方的限制,而可以继续执行其他任务。它提供了一个临时存储区,用于存放发送的消息,直到接收方准备好接收。
- 零容量: 表示没有任何缓冲区,发送方必须等待接收方
- 无限容量:允许存储任意大小的消息,发送方不需要等待
- 有限容量:限制了可以存储的消息数量(通信链路缓冲队列满时,发送方需要等待)
- Link,指连接两个节点或设备的物理或逻辑通道。它可以是通过电缆、光纤、无线信号等媒介实现的物理连接,也可以是通过网络协议在逻辑上建立的连接。
消息包大小
Message packet,通信系统中传输数据的基本单位。它将数据按照一定的格式封装成一个完整的单元,以便在网络中传输和交换。
- 固定大小的消息包 (Fixed sized message):每个消息都具有相同的固定字节大小。这种类型的消息包更容易进行缓冲和管理,也有助于有效地利用带。因为接收方可以预先分配固定大小的缓冲区来接收消息,进行带宽管理和调度。
- 有类型的消息包 (Typed message):消息具有明确定义的数据类型,在强类型语言环境中很有用,确保在发送和接收消息时进行类型检查和一致性验证,以减少数据错误和不一致性。
共享内存
Shared Memory
这种通信方式通常需要在同一台主机上,允许多个进程共享同一块内存区域,而无需进行复制或数据传输。
直接通信
发送进程直接把消息发给目标进程
- Implicit communication through read/write operations. Highly efficient , no communication protocols.
- 直接读取和写入共享内存中的数据,无需显式地发送或接收消息。
- Need synchronisation mechanisms
- 由于多个进程同时访问共享内存,需要采取同步机制来确保数据的一致性和正确性。
消息传递
Message passing,一种进程直接通过发送 (send) 和接收 (recieve) 消息进行信息交换的机制。每个进程都有自己的独立地址空间,不共享内存,通过共享实体(进程,线程等),每个实体都有自己的数据和状态。
间接通信
通过系统调用和内核的中转,来相互传递消息
管道
代码参考 Lab 5
一种半双工的通信方式,数据只能在一个方向上进行传输。
它可表示为两个文件描述符(分别代表读写端)加一段内核空间中的内存。
无名管道
Unnamed Pipe,只支持父子进程和兄弟进程间的通信
- 它没有文件系统中的对应文件,只存在于内存中。
- 只能实现单向通信,只能一端选择写,另一端选择读(不能改变)
- 父进程关闭读描述符,只能向管道写数据;子进程关闭写描述符,只能从管道读数据
- 父进程关闭写描述符,只能向管道读数据;子进程关闭读描述符,只能从管道写数据``
通常管道两端的进程会各自关闭管道的一个文件描述符,如
命名管道
Named Pipe,也称 FIFO (First in, First out),支持任意两个进程间的通信
- 它在磁盘上有对应的节点,但没有数据块,只是拥有一个名字和相应的访问权限。
即它在文件系统中虽然可见,可以视为一种特殊文件,但是仍只在内存当中。
- 可以实现双向通信,两端都可以选择读或写(交替操作),但本质在给定的时刻只能进行单向通信。即当前可以选择 端写 端读,过一会选择 端写 端写,但 端不能同时读写。
消息队列
代码参考 Lab 5
Message Queue,一种操作系统维护的以结构数据为基本单位的通信机制
- 每个消息 (Message) 是一个字节序列,有自己的类型标识
相同类型标识的消息组成按先进先出顺序组成一个队列
- 消息队列允许进程以整个消息的形式异步地 (asynchronously) 交换数据,无需等待对方的到达。消息具有关联的优先级,按优先级顺序排队。
主要 API
mq_open()
: creates a new message queue or opens an existing queue, returning a message queue descriptor for use in later calls.
mq_send()
: writes a message to a queue.
mq_receive()
: reads a message from a queue.
mq_close()
mq_unlink()
: removes a message queue name and marks the queue for deletion when all processes have closed it.
内部结构
在C语言中,
struct
是一种自定义的数据类型,用于组合多个不同类型的变量(成员)在一个逻辑实体中。struct mq_attr {
- long
mq_flags;
: flags 0 or O_NONBLOCK semantics
- long
mq_maxmsg;
: max number of messages on queue
- long
mq_msgsize;
: max message size (in bytes)
- long
mq_curmsgs;
: num messages currently in queue
};
mq_getattr()
示例代码
套接字
代码参考 Lab 6
Network Socket,一种底层的网络编程接口
沿着消息传递路径的每个点上都必须运行一个“能够理解相同消息协议”的通信子系统,即客户端和服务器之间建立连接需要使用特定的协议,如 TCP/IP 或 UDP。
bind()
: Associate socket with named IP port
listen()
: Marks the socket as a passive socket that will be used to accept incoming connection requests using accept.
在套接字通信中,可以根据性能需求来权衡可靠性和传递速度,选择不同方式:
- 数据报 (Datagram):无连接的方式,每个消息都是独立的实体,类似于发送邮件。传递速度较快,但可靠性较低,因为消息可能会丢失或乱序。
- 连接导向 (Connection-Oriented):建立了一个稳定的连接通道,类似于打电话。可以通过这个连接传递多个消息,并确保它们按顺序到达目标。连接导向方式提供了更高的可靠性,但可能会牺牲一些传递速度。
远程过程调用
代码参考 Lab 6
Remote procedure call,RPC
一种在 Socket 的基础上构建的通信机制(底层通常使用 Socket 来进行数据传输),允许开发人员像调用本地函数一样调用远程函数,而无需关心底层的网络通信细节。
(Comms, Communications) Stub
存根,指一个用于简化真实通信组件的占位实现。比如提供与服务器相似的接口,模拟网络协议等,以便进行应用程序的开发和测试。
工作原理
(待补充,Lecture9 的 )
- Find the server’s port address
- Data Format Translation
🔴 远程方法调用:Remote Method Invocation, RMI,用于实现 RPC 的 Java API,其原理与 RPC 基本一致,只不过是针对面向对象的环境。
总结
Type | Summary |
Shared Memory | Allows multiple processes to access the same memory region in one computer. |
Pipe | Fast memory based, stream oriented, between related processes.
Data can only be transmitted in one direction. |
Named Pipe | Like pipes but uses shared files, useable by unrelated processes |
Message Queue | Asynchronous whole message communication with priority ordering |
Socket | Low level internet communication abstraction generally over TCP/IP |
Remote procedure call | Allows execution of programson in a remote computer.
Simplifies client/server programming |
Pipe | Message Queue |
No internal structure, just a byte stream | Internal structure and geometry set by user |
Cannot distinguish between content of different writers | Separate messages are distinguishable |
No priority for writer | Queue sorted on message priority |
Cannot determine state of pipe content | Process can determine status of queue, maximum msg size |