YanranのblogYanranのblog
主页
知识学习
工具积累
其他
GitHub
主页
知识学习
工具积累
其他
GitHub
  • 知识学习

    • README
    • C++基础
    • C++基础入门
    • C++提高编程
    • C++核心编程
    • Git
    • Java
    • Linux基础
    • MFC
    • Qt
    • 多线程
    • Vue
    • 操作系统
    • 数据结构
    • 计算机基础
    • 计算机编译
    • 计算机网络

操作系统

IPC

  • 进程间通信(IPC,Inter-Process Communication)是操作系统中多个进程交换数据、协同工作的核心机制。不同的 IPC 方式适用于不同的场景,其设计原理、性能和适用范围差异较大。
  • 常见进程间通信方式及原理如下

1.管道(Pipe)与命名管道(FIFO)

  • 原理:管道是内核中的一段环形缓冲区,通过 “读 / 写” 操作实现进程间字节流传递,本质是 “文件描述符” 的抽象。
  1. 匿名管道(Pipe):仅用于父子进程或亲缘进程(如 fork 创建的子进程),生命周期随进程结束而销毁,无文件名,通过pipe()系统调用创建。
  2. 命名管道(FIFO):可用于非亲缘进程,通过文件系统中的路径(如/tmp/myfifo)标识,生命周期独立于进程,通过mkfifo()创建,读写方式与文件一致。
  • 实际应用
  1. 匿名管道:Shell 中的管道命令(如ls -l | grep .txt),父进程(ls)写入数据,子进程(grep)读取,实现命令协作。
  2. 命名管道:本地服务间的简单通信,如日志收集(应用进程写入日志到 FIFO,日志进程从 FIFO 读取并存储)。
  3. 典型场景:轻量、单向、低延迟的本地进程通信,无需跨网络。

2.消息队列(Message Queue)

  • 原理:内核维护的消息链表,进程可按 “类型” 发送 / 接收消息(消息包含类型和数据),支持异步通信,无需进程同步等待。
  1. 发送方通过msgsnd()将消息放入队列,接收方通过msgrcv()按类型提取消息(可过滤特定类型)。
  2. 消息有大小限制(通常几 KB),队列总容量有限制。
  • 实际应用
  1. 分布式任务调度:如公司内部的任务分配系统(调度进程向队列发送任务, Worker 进程按类型领取任务)。
  2. 异步通知:电商订单系统中,支付进程完成后向消息队列发送 “支付成功” 消息,物流进程监听并处理。
  • 局限性:不适合高频、大数据量场景(性能低于共享内存),目前逐步被分布式消息中间件(如 RabbitMQ)替代。

3.共享内存(Shared Memory)

  • 原理:多个进程将同一块物理内存映射到各自的虚拟地址空间,直接读写内存实现通信,是速度最快的 IPC 方式(无需内核中转数据)。
  1. 需配合同步机制(如信号量)防止并发读写冲突。
  2. 通过shmget()(创建)、shmat()(映射到进程)等系统调用实现。
  • 实际应用
  1. 高频实时数据交换:金融交易系统(如股票行情推送,行情服务器将实时价格写入共享内存,多个交易进程直接读取,延迟 < 1ms)。
  2. 大型数据共享:视频处理软件(如 Adobe Premiere,多个滤镜进程共享同一视频帧数据,避免数据拷贝)。
  3. 典型公司:高频交易公司(如 Jump Trading)、实时渲染引擎(如 Unity 引擎的多进程渲染)。

4.信号量(Semaphore)

  • 原理:内核维护的计数器,用于控制多个进程对共享资源的访问(同步 / 互斥),本身不传递数据,仅用于 “权限控制”。
  1. P 操作:计数器 - 1,若计数器 < 0 则阻塞进程(等待资源)。
  2. V 操作:计数器 + 1,若有进程阻塞则唤醒一个。
  3. 常用于保护共享内存、消息队列等资源的并发访问。
  • 实际应用
  1. 共享资源互斥:多进程读写同一数据库文件时,通过信号量保证 “同一时间只有一个进程写入”。
  2. 生产者 - 消费者模型:如电商库存系统(生产者进程增加库存,消费者进程减少库存,信号量控制库存不为负)。

5.信号(Signal)

  • 原理:操作系统向进程发送的异步事件通知(类似 “软件中断”),可携带极少信息(仅信号编号),用于触发进程预设的处理函数。
  1. 常见信号:SIGINT(Ctrl+C 终止)、SIGKILL(强制杀死进程)、SIGCHLD(子进程退出通知)。
  2. 进程通过signal()或sigaction()注册信号处理函数。
  • 实际应用
  1. 异常处理:进程崩溃时通过SIGSEGV(段错误)捕获并记录日志(如 Linux 的 core dump)。
  2. 进程控制:父进程通过SIGTERM优雅终止子进程(子进程收到后释放资源再退出)。
  3. 典型场景:简单的事件通知(如进程退出、超时提醒),不适合传递复杂数据。

6.套接字(Socket)

  • 原理:基于网络协议栈的通信机制,支持同一主机或跨网络的进程通信,通过 “IP 地址 + 端口” 标识进程,支持 TCP(可靠流)和 UDP(不可靠报)协议。
  1. 本地套接字(Unix Domain Socket):用于同一主机进程,通过文件系统路径标识(如/var/run/mysocket),性能优于网络套接字。
  2. 网络套接字:用于跨主机通信,如互联网服务。
  • 实际应用
  1. 跨主机通信:所有互联网服务(如浏览器与 Web 服务器通过 TCP 通信,即时通讯工具如微信用 UDP 传输语音)。
  2. 本地高可靠通信:数据库客户端与服务端(如 MySQL 客户端通过本地 Socket 连接服务器,避免网络开销)。
  3. 典型公司:腾讯(微信消息传输)、阿里(分布式服务间调用)、谷歌(跨数据中心通信)。

7.文件映射(Memory-Mapped File)

  • 原理:将磁盘文件映射到进程的虚拟内存,进程读写内存即等效于读写文件,多进程映射同一文件可实现共享数据。
  1. 原理类似共享内存,但数据持久化到磁盘,适合大数据量(GB 级)共享。
  • 实际应用
  1. 大型文件处理:视频编辑软件(如 Final Cut Pro)映射 4K 视频文件到内存,多进程(解码、渲染)直接操作内存数据。
  2. 数据库存储:SQLite 通过文件映射实现高效的磁盘 IO,避免频繁的read()/write()系统调用。

主流 IPC 方式及适用场景

场景主流方式核心技术 / 库典型业务
本地轻量通信命名管道(FIFO)、本地 Socketmkfifo()、socket(AF_UNIX)、Qt 的QLocalSocket日志收集、桌面应用插件通信
高频实时数据交换共享内存 + 信号量System V 共享内存、boost::interprocess金融行情、实时渲染
跨网络 / 跨主机通信网络 Socket(TCP/UDP)BSD Socket、Boost.Asio、Qt 的QTcpSocket互联网服务、分布式系统
异步消息传递消息队列(分布式中间件)RabbitMQ、Kafka(基于 Socket 封装)电商订单、日志异步处理
简单事件通知信号(Signal)sigaction()、Qt 的QProcess::errorOccurred

IPC-C++原生及标准库

  • 管道 / 命名管道:通过pipe()(匿名)、mkfifo()(命名)+ open()/read()/write()系统调用,适合轻量通信。
  • 共享内存:shmget()/shmat()(System V)或mmap()(POSIX),配合sem_init()(信号量)同步,适合高性能场景。
  • Socket:通过 BSD Socket API(socket()/connect()/send())实现,跨平台需处理 Windows/Linux 差异。
  • 第三方库:Boost.Interprocess(封装共享内存、消息队列)、Boost.Asio(跨平台 Socket 通信),解决原生 API 的跨平台问题。

Qt中IPC封装

IPC 方式Qt 类 / 方法适用场景
父子进程管道通信QProcess主进程启动子进程并传递命令 / 数据(如 IDE 调用编译器)。
本地 Socket 通信QLocalServer/QLocalSocket同一主机非亲缘进程(如桌面应用与后台服务)。
网络 Socket 通信QTcpServer/QTcpSocket、QUdpSocket跨主机通信(如客户端 - 服务器应用)。
共享内存QSharedMemory高频数据共享(如多窗口应用共享大型缓存)。
信号量同步QSemaphore配合共享内存控制并发访问。
Prev
Vue
Next
数据结构