不同的进程在各自的房间内运行, 每个房间有自己的编号pid, 进程之间互不干涉, 房间内有许多种与外界通信的方式, 他们有各自的用途和特性, 分布在墙壁上; 房间内还分成多个区域, 分别是: 代码区(.text), 已初始化的全局/静态数据区(.data), 未初始化的全局/静态数据区(.bss), 堆, 栈, 内存映射区, 环境变量与命令行参数区, 内核空间
内存区域名词解释
代码区(.text)
这是整个房间的执行手册, 只可以执行不可以更改
- 存放程序的机器指令的地方
- 只读 + 可执行
- 多个进程运行同一程序时,可以共享同一份 .text(节省内存)
- 由
exec()加载,从可执行文件(如 ELF)中读取.text
已初始化的全局/静态数据区(.data)
房间的初始化时就存在的数据
- 可读可写
- 程序启动时就分配好空间和初始值
未初始化的全局/静态数据区(.bss)
留给未初始化的全局/静态变量的空间, 初始化房间时一次性清零
- 在程序加载时自动清零
- 不占用可执行文件空间(只记录大小),节省磁盘空间
堆
房间里的“可扩展货架”——按需搭建,用完可拆
栈
房间里的“工作台”——临时操作,用完即清
内存映射区
房间的“外接模块区”——插入外部功能模块
-
堆和栈之间,或单独区域
-
作用:通过
mmap()映射以下内容:
- 动态链接库(如
libc.so) - 文件映射(
mmap文件) - 匿名映射(用于大块内存分配)
- 线程栈(
pthread_create使用)
- 动态链接库(如
-
可读、可写、可执行(取决于映射方式)
-
是现代程序加载共享库的主要方式
环境变量与命令行参数区
房间入口处的“任务说明书”和“环境配置单
- 栈的最顶端(启动时)
内核空间(Kernel Space)
房间顶部的“特权控制区”——只有通过“请求孔”才能短暂进入
交互
通信机制
基于内核的ipc
管道
-
匿名管道
通过系统调用孔,使用
pipe()命令, 内核会返回两个文件描述一个用于读数据, 另一个用于写数据; 通常使用一个int fd[2]来存储这两个描述符, 1是写入端, 0是读入端,如果系统调用成功, 那么在墙上就出现了两个分别标记这1和0的两个通道口, 这两个通道直接通向内核, 所有的数据都将先到达内核缓冲区,再到达另一端. 除此之外, 这两个通道在同一时间只能操作一个, 只有所有的写端或者读端全部关闭, 才可以打开另一端, 这使用内核来控制的.
- 单向通信(半双工)
- 基于字节流
- 只能在父子进程间使用
- 命令行中
|符号的实现基础 - 系统调用:
pipe()
-
命名管道(FIFO)
“命名管道(FIFO)就像是一个带名字的“公共信箱”,存在于文件系统中。任何知道其路径名的进程都可以通过名字打开它,进行通信。它的通信机制与匿名管道类似:基于字节流、半双工、数据在内核缓冲区中传递。
与匿名管道不同的是,命名管道有名字、不需要进程间有亲缘关系,并且可以在多个无关进程间共享。
虽然管道文件本身可以长期存在(直到被删除),但其中的数据仍是临时的,不会持久化存储。
- 通过文件系统中的命名节点访问
- 无亲缘关系的进程也可使用
- 系统调用:
mkfifo()
-
特点:简单易用,适合少量数据传输
消息队列
通过系统调用, 在内核中申请一个“带分类邮箱”的邮局系统,每封信(消息)有编号(类型)、内容,收件人可以按类型取信。即使进程关闭, 邮箱也不会消失
- 消息的链表结构,存储在内核中
- 通信过程:
- 进程A创建消息队列:
msgget() - 发送消息:
msgsnd() - 进程B接收消息:
msgrcv()
- 进程A创建消息队列:
- 特点:
- 支持不同类型消息(消息优先级)
- 允许非阻塞操作
信号
- 异步通知机制(如
SIGINT、SIGKILL) - 发送信号:
kill()系统调用 - 接收处理:注册信号处理函数
signal()或sigaction() - 特点:轻量级但只能传递信号值,不能携带数据
信号量
- 用于进程间同步(非数据交换)
- 控制对共享资源的访问(类似锁机制)
- 操作:
- P操作(等待/减操作)
sem_wait() - V操作(释放/加操作)
sem_post()
- P操作(等待/减操作)
- 特点:适用于复杂的同步场景
共享内存
- 最高效的IPC方式
- 工作机制:
- 创建共享内存区域:
shmget() - 映射到进程地址空间:
shmat() - 直接读写内存
- 分离映射:
shmdt()
- 创建共享内存区域:
- 关键问题:
- 需要同步机制(如信号量)避免竞态条件
- 实现复杂,但有最佳性能
基于文件系统的ipc
内存映射文件
- 文件映射到进程的虚拟地址空间
- 系统调用:
mmap() - 特点:
- 文件修改自动同步到内存
- 适合大文件操作
- 可在进程间共享
文件锁定
- 通过
fcntl()或flock()实现 - 协作机制:
- 写时获取排他锁
- 读时获取共享锁
基于网络的ipc
套接字
- 最通用的IPC机制
- 类型:
- UNIX域套接字(本地进程间)
- 网络套接字(跨机器通信)
- 过程:
- 服务器:
socket()→bind()→listen()→accept() - 客户端:
socket()→connect()
- 服务器:
- 特点:
- 支持TCP(可靠流)和UDP(不可靠数据报)
- 可用于分布式系统
高级抽象机制的ipc
rpc
- 远程过程调用框架
- 工作流程:
- 客户端调用本地代理(stub)
- stub将调用信息序列化并发送
- 服务器stub反序列化并执行实际函数
- 结果返回客户端
- 代表实现:
- gRPC
- CORBA
- Java RMI
Dbus
- 面向桌面环境的IPC系统
- 用于Linux桌面应用间通信
- 特点:
- 基于消息传递
- 支持对象模型