当前位置: 首页 > news >正文

Linux18--进程间的通信总结

12.6进程间的通信对比

首先进程间的通信是指进程与进程之间的相互通信,分为单双工,全双工,半双工。本质是描述进程间数据传输的双向性与同时性,核心区别在于数据能否双向流动、是否可同时双向传输。以下是具体分类、对应 IPC 方式及特性对比:

单工:数据只能从一个进程(发送方)单向传输到另一个进程(接收方),无法反向传输。

特点:通信方向固定,接收方不能向发送方反馈数据,如进程向另一个进程发送 SIGUSR1 信号,仅单向通知,无返回。

半双工:数据可在两个进程间双向传输,但同一时间只能沿一个方向传输(类似 “对讲机”,一方说话时另一方只能听)。管道(Pipe):匿名管道是典型半双工 IPC,进程 A 写入数据时,进程 B 需等待读取完成后才能反向写入;

全双工:数据可在两个进程间同时双向传输(类似 “电话”,双方可同时说话)。套接字(Socket)消息队列,共享内存 + 信号量.

维度

单工(Simplex)

半双工(Half-Duplex)

全双工(Full-Duplex)

通信方向

单向固定(A→B,不可 B→A)

双向可切换(A→B 或 B→A,不同时)

双向同时(A→B 且 B→A 可并行)

数据冲突风险

无(仅单向传输)

有(需同步避免同时发送)

无(独立通道 / 缓冲区)

效率

低(无法反馈,仅单方向可用)

中(需轮流传输,有等待开销)

高(同时双向传输,无等待)

典型 IPC 方式

日志管道、单向信号

匿名管道、FIFO(默认)

TCP Socket、双向共享内存

适用场景

单向通知(日志、状态上报)

简单双向交互(如命令 - 响应,无实时性要求)

实时双向交互(如聊天、数据同步)

12.6.1进程间通信机制对比总览

下表总结了Linux中主要IPC机制的核心特性,方便你快速比较和选型:

IPC机制

通信方式

进程关系

同步要求

性能

主要用途

内核持久性

匿名管道

单向字节流

必须有亲缘关系

自带同步

中等

父子进程简单数据流

命名管道(FIFO)

单向字节流

无需亲缘关系

自带同步

中等

任意进程间数据流

消息队列

结构化的消息

无需亲缘关系

部分自带同步

中下

格式化的消息传递

共享内存

内存直接访问

无需亲缘关系

需要额外同步

最高

大数据量高性能共享

信号量

计数器同步

无需亲缘关系

原子操作

进程同步与互斥

信号

异步事件通知

无需亲缘关系

信号处理函数

事件通知、进程控制

Socket

网络/本地数据流

无需亲缘关系

可配置同步

网络及本地进程通信

1.管道(Pipe):管道是Unix系统中最古老的IPC形式,分为匿名管道和命名管道。

匿名管道特性:

  • 通过 pipe() 系统调用创建,返回两个文件描述符 fd[0] (读端)和 fd[1] (写端)
  • 只能用于具有亲缘关系的进程间通信(如父子进程、兄弟进程)
  • 数据以先进先出(FIFO)方式流动,自带同步机制
  • 生命周期随进程结束而销毁

命名管道(FIFO)特性:

  • 通过 mkfifo() 创建,在文件系统中有路径名
  • 允许无亲缘关系的进程通过文件名访问同一管道
  • 其余特性与匿名管道基本相同

2. 消息队列

消息队列是由内核维护的消息链表,克服了管道的一些局限性。

核心特点:

  • 支持结构化的消息传递,每个消息包含类型标识和数据体
  • 进程可以按消息类型进行选择性接收,不严格遵循FIFO顺序
  • 消息可持久化在内核中,即使进程退出消息仍保留
  • 适合需要可靠、结构化消息传递的场景

系统调用:

#include <sys/msg.h>int msgget(key_t key, int msgflg); // 创建/获取消息队列int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); // 发送消息ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); // 接收消息int msgctl(int msqid, int cmd, struct msqid_ds *buf); // 控制消息队列

3. 共享内存

共享内存是最快的IPC方式,因为它避免了数据复制。

工作原理:

  • 多个进程映射同一块物理内存区域到各自的地址空间
  • 进程可以直接读写该内存区域,零拷贝操作
  • 需要配合信号量等同步机制防止数据竞争

使用步骤:

#include <sys/shm.h>// 1. 创建共享内存段int shmid = shmget(key_t key, size_t size, int shmflg);// 2. 映射到进程地址空间void *shm_ptr = shmat(int shmid, const void *shmaddr, int shmflg);// 3. 使用共享内存(直接读写)strcpy(shm_ptr, "Hello Shared Memory");// 4. 分离共享内存shmdt(const void *shmaddr);// 5. 控制(删除)共享内存shmctl(int shmid, int cmd, struct shmid_ds *buf);

4. 信号量(Semaphore)

信号量主要用于进程同步和互斥,而不是数据传输。

核心概念:

  • 是一个计数器,用于控制多个进程对共享资源的访问
  • P操作(等待):信号量值减1,如果值小于0则进程阻塞
  • V操作(发送):信号量值加1,如果有进程等待则唤醒一个

System V信号量使用:

#include <sys/sem.h>int semget(key_t key, int nsems, int semflg); // 创建/获取信号量集int semop(int semid, struct sembuf *sops, unsigned nsops); // P/V操作int semctl(int semid, int semnum, int cmd, ...); // 控制信号量

5. 信号(Signal)

信号是用于通知进程某事件已发生的异步通信机制。

特点:

  • 用于处理异常、中断等紧急事件
  • 信号处理函数需要是可重入的,避免在信号处理中调用非可重入函数
  •  SIGKILL 和 SIGSTOP 信号不能被捕获、阻塞或忽略

信号处理示例:

#include <signal.h>void signal_handler(int sig) {printf("收到信号: %d\n", sig);}int main() {signal(SIGINT, signal_handler); // 捕获Ctrl+Cwhile(1) pause(); // 等待信号return 0;}

12.6.2实际应用场景选择指南

根据通信需求选择:

  1. 简单数据流,有亲缘关系匿名管道
  • 如:shell命令管道 ls | grep "test  " 
  1. 简单数据流,无亲缘关系命名管道
  • 如:不同终端间的进程通信
  1. 结构化消息,需要可靠性消息队列
  • 如:任务调度系统,生产者-消费者模式
  1. 高性能,大数据量共享共享内存+信号量
  • 如:数据库缓存、科学计算、实时数据处理
  1. 纯同步需求信号量
  • 如:保护临界资源,控制进程执行顺序
  1. 事件通知、异常处理信号
  • 如:处理Ctrl+C、子进程终止通知

12.6.3 重要注意事项

1. 同步问题

  • 共享内存必须配合同步机制(如信号量),否则会出现数据竞争
  • 消息队列和管道自带一定的同步,但复杂场景仍需额外同步

2. 资源管理

  • System V IPC(消息队列、信号量、共享内存)是内核持久的,使用后必须显式删除
  • 避免资源泄漏:及时关闭文件描述符、删除IPC对象

3. 错误处理

  • 所有IPC系统调用都应检查返回值,确保程序健壮性
  • 考虑边界情况:如管道破裂(SIGPIPE)、消息队列满等

4. 性能考量

  • 共享内存最快,但编程复杂度最高
  • 管道和消息队列适合中等数据量
  • 信号量同步开销较小

调试与监控命令

# 查看系统IPC状态ipcs# 查看共享内存段ipcs -m# 查看消息队列ipcs -q# 查看信号量ipcs -s# 删除IPC对象ipcrm -m <shmid> # 删除共享内存ipcrm -q <msqid> # 删除消息队列ipcrm -s <semid> # 删除信号量

12.6.4 总结

掌握Linux进程间通信是中级开发的核心技能。关键要点如下:

  1. 根据需求选型:简单数据流用管道,结构化消息用消息队列,高性能需求用共享内存,纯同步用信号量
  1. 理解特性差异:亲缘关系要求、同步机制、性能特点、持久性等
  1. 重视同步安全:特别是共享内存必须配合同步机制
  1. 做好资源管理:及时释放IPC资源,避免泄漏
http://www.dtcms.com/a/528292.html

相关文章:

  • 基于脚手架微服务的视频点播系统-脚手架开发部分-FFmpeg,Etcd-SDK的简单使用与二次封装
  • 【教学类-120-01】20251025旋转数字
  • 制作网站多少钱一个有哪些做企业点评的网站
  • 网站会员营销上海注册公司哪家好
  • 【深度学习新浪潮】深入理解Seed3D模型:参数化驱动的下一代3D内容生成技术
  • GitHub等平台形成的开源文化正在重塑和人家
  • 免费网站收录入口有了域名空间服务器怎么做网站
  • 5.go-zero集成gorm 和 go-redis
  • Linux系统入门:System V进程间通信
  • 第一章 蓝图篇 - 全景认知与项目设计
  • mormot.net.server.pas源代码分析
  • 丹阳网站建设价位php网站搭建
  • 【工具分享】另一个免费开源的远程桌面服务-Apache Guacamole
  • RabbitMQ TTL机制详解
  • XSL-FO 对象:深度解析与实际应用
  • 在JavaScript / Node.js / 抖音小游戏中,使用tt.request通信
  • 两学一做网站源码wordpress 柚子皮下载
  • Go slog 日志打印最佳实践指南
  • Go的垃圾回收
  • 珠海网站管理公司国际公司名字
  • 自动化模型学习器——autoGluon
  • 长沙网站建设招聘外贸做那种网站有哪些
  • 浏览器卡顿内存高?傲游浏览器三核加速,网页加载效率提升60%
  • 研发部门验收流程
  • 贪心算法 with Gemini
  • 掌握 Rust:从内存安全到高性能服务的完整技术图谱
  • [Java]重学Java-Java平台
  • Bash Shell 脚本编程入门详解
  • 打造高清3D虚拟世界|零基础学习Unity HDRP高清渲染管线(第七天)
  • 营销型网站建立费用手机端网站开发页