目录
一、前言
1.1 什么是进程间通信?
进程间通信(IPC)是操作系统中的一种机制,用于不同进程之间进行数据和信息的交换与共享。它允许并发执行的进程协调工作,共享资源,或者通过消息传递进行协作。在一个多任务的操作系统中,多个进程可以同时运行,但是这些进程是相互独立的,它们有自己的地址空间和上下文,无法直接访问对方的内存空间。如果多个进程需要协作来完成某项任务,或者需要共享某些数据,就需要使用进程间通信机制来进行通信和协作。
1.2 进程间通信的作用?
(1)实现进程间数据共享:进程间通信可以使不同进程之间共享数据,避免了数据复制的开销,提高了系统的性能。共享内存和消息队列是实现进程间数据共享的常用方法。
(2)提高系统的可靠性:进程间通信可以将多个进程组织成一个整体,使得它们可以协同工作,提高了系统的可靠性。例如,多个进程可以共同访问同一个文件,避免了数据的竞争和冲突。
(3)实现进程间协作:进程间通信可以使进程之间相互协作,共同完成任务。一个进程可以向另一个进程发送请求,请求另一个进程提供某些服务,如打印文件等。管道、消 息队列、信号量、共享内存等机制都可以用来实现进程间协作。
(4)提高系统的安全性:进程间通信可以实现不同进程之间的数据隔离和保护,从而提高了系统的安全性。例如,共享内存和消息队列可以通过权限控制来保护数据的安全
1.3 进程间通信的机制?
根据 IPC 机制所依赖的资源类型可以划分为 基于系统资源的 IPC 机制和基于文件系统的 IPC 机制。基于文件系统的 IPC 机制主要是通过操作文件系统中的文件和管道来进行进程间的通信,这些通信机制依赖于文件系统提供的特定功能,如普通文件、命名管道、套接字文件等。而基于系统资源的进程间通信机制主要是利用系统内核中提供的一些共享资源来实现进程间的通信,这些共享资源包括共享内存、消息队列、信号量等。这些通信机制依赖于操作系统内核所提供的特定功能,如内存管理、进程调度、信号处理等。
IPC包括多种技术,如管道、消息队列、共享内存和信号量等。每种IPC方式都有其适用的场景和特性,例如管道适用于父子进程之间的单向通信,消息队列则支持异步的消息传递,共享内存则允许进程直接共享物理内存。通过这些IPC机制,进程可以安全地交换信息,协同完成复杂任务,提高系统的效率和灵活性。
1.4 IPC机制介绍
(1)管道(Pipe):管道是一种基于文件描述符的通信机制,可以实现进程间的单向通信,分为无名管道和有名管道(有时候也被叫命名管道)两种。无名管道是在进程创建时自动创建的,只能在具有亲缘关系的进程间使用;有名管道则是由系统中的一个特殊文件来实现的,可以在任意进程之间进行通信。
(2)消息队列(Message Queue):消息队列是一种基于内核对象的通信机制,可以实现进程间的异步通信。消息队列中包含多个消息,每个消息都有一个特定的类型和长度,进程可以通过指定消息类型来选择接收特定类型的消息。
(3)共享内存(Shared Memory):共享内存是一种基于内核对象的通信机制,可以让多个进程共享同一块物理内存。多个进程可以同时访问这块内存,从而实现快速、高效的数据共享。共享内存需要考虑数据同步和互斥等问题,以保证数据的一致性和正确性。
(4)信号量(Semaphore):信号量是一种基于内核对象的通信机制,用于实现进程间的同步和互斥。信号量可以用于实现多个进程之间的资源共享和互斥,通过对信号量进行加锁和解锁操作,可以控制多个进程之间的访问顺序和数量。
(5)Socket:Socket 是一种基于网络的通信机制,可以实现不同计算机之间的进程间通信。 Socket 可以实现进程间的数据传输和通信,可以通过网络协议(如 TCP、UDP 等)来进行数据 传输和路由。
总结一下:
机制名称 | 机制类型 | 实现原理 | 数据共享 | 进程关系 | 通信方式 |
无名管道 | 基于文件描述符 | 单向通信 | 否 | 有血缘关系进程 | 无名管道 |
有名管道 | 基于文件描述符 | 单向通信 | 否 | 无关进程 | 有名管道 |
消息队列 | 基于内核对象 | 异步通信 | 是 | 无关进程 | 先进先出 |
共享内存 | 基于内核对象 | 共享同一块物理内存 | 是 | 无关进程 | 直接读写 |
信号量 | 基于内核对象 | 同步与互斥 | 是 | 无关进程 | 加锁/解锁 |
Socket | 基于网络 | 跨网络的进程间通信 | 是 | 无关进程 | 客户端和服务端 |
二、IPC机制
注:这里主要是POSIX下的IPC机制。
2.1 无名管道
2.1.1 概念
无名管道是一种单向的、字节流的通信管道,可以在进程之间传递数据。由于是匿名管道, 所以无法通过文件系统来访问它,只能通过文件描述符在具有亲缘关系的进程之间使用,如父 子进程、兄弟进程等。
无名管道实际上是一种特殊的文件,它存在于内存中,当一个进程创建了一个无名管道之 后,它实际上创建了两个文件描述符,一个用于读取数据,另一个用于写入数据。在进程调用 fork()函数之后,子进程会继承父进程的文件描述符,因此可以通过这两个文件描述符实现进程间通信。
特点:
1)单向传输:无名管道是单向的,数据只能从管道的一端进入&#