不同的进程在各自的房间内运行, 每个房间有自己的编号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()
  • 特点:简单易用,适合少量数据传输

消息队列

通过系统调用, 在内核中申请一个“带分类邮箱”的邮局系统,每封信(消息)有编号(类型)、内容,收件人可以按类型取信。即使进程关闭, 邮箱也不会消失

  • 消息的链表结构,存储在内核中
  • 通信过程:
    1. 进程A创建消息队列:msgget()
    2. 发送消息:msgsnd()
    3. 进程B接收消息:msgrcv()
  • 特点
    • 支持不同类型消息(消息优先级)
    • 允许非阻塞操作

信号

  • 异步通知机制(如 SIGINTSIGKILL
  • 发送信号:kill()系统调用
  • 接收处理:注册信号处理函数 signal()sigaction()
  • 特点:轻量级但只能传递信号值,不能携带数据

信号量

  • 用于进程间同步(非数据交换)
  • 控制对共享资源的访问(类似锁机制)
  • 操作:
    • P操作(等待/减操作)sem_wait()
    • V操作(释放/加操作)sem_post()
  • 特点:适用于复杂的同步场景

共享内存

  • 最高效的IPC方式
  • 工作机制:
    1. 创建共享内存区域:shmget()
    2. 映射到进程地址空间:shmat()
    3. 直接读写内存
    4. 分离映射:shmdt()
  • 关键问题
    • 需要同步机制(如信号量)避免竞态条件
    • 实现复杂,但有最佳性能

基于文件系统的ipc

内存映射文件

  • 文件映射到进程的虚拟地址空间
  • 系统调用:mmap()
  • 特点
    • 文件修改自动同步到内存
    • 适合大文件操作
    • 可在进程间共享

文件锁定

  • 通过 fcntl()flock()实现
  • 协作机制:
    • 写时获取排他锁
    • 读时获取共享锁

基于网络的ipc

套接字

  • 最通用的IPC机制
  • 类型
    • UNIX域套接字(本地进程间)
    • 网络套接字(跨机器通信)
  • 过程
    • 服务器:socket()bind()listen()accept()
    • 客户端:socket()connect()
  • 特点
    • 支持TCP(可靠流)和UDP(不可靠数据报)
    • 可用于分布式系统

高级抽象机制的ipc

rpc

  • 远程过程调用框架
  • 工作流程:
    1. 客户端调用本地代理(stub)
    2. stub将调用信息序列化并发送
    3. 服务器stub反序列化并执行实际函数
    4. 结果返回客户端
  • 代表实现
    • gRPC
    • CORBA
    • Java RMI

Dbus

  • 面向桌面环境的IPC系统
  • 用于Linux桌面应用间通信
  • 特点
    • 基于消息传递
    • 支持对象模型