跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

Linux 进程间通信进阶:消息队列与信号量详解

Linux 进程间通信进阶主要涵盖消息队列与信号量两大核心机制。消息队列作为系统级 IPC,通过有类型数据块实现进程间通信,需配合 key 值管理。信号量本质是计数器,用于解决多进程访问共享资源时的并发读写问题,提供互斥与同步能力。关键接口包括 semget 创建、semop 操作及 semctl 控制,结合临界区保护确保数据安全。

战神发布于 2026/3/23更新于 2026/10/2481 浏览
Linux 进程间通信进阶:消息队列与信号量详解

7 消息队列

7.1 概念说明

这里讨论的消息队列是操作系统层面的 IPC 机制,不同于应用组件中的消息中间件。简单来说,就是内核维护的一个队列结构,用于进程间传递数据。

7.2 工作原理

消息队列属于系统级 IPC,由用户设置一个共享的 key 值(A、B 进程均可见),双方约定通过该 key 访问同一个队列。内核中会维护相应的描述结构体。

消息队列结构

消息队列和共享内存一样,都是系统级的 IPC。如果数据节点只包含数据,操作系统如何区分归属?必须保证数据块是有类型的。因此,消息队列是一种向另一个进程发送有类型数据块的方式。

核心系统调用如下:

IPC 接口概览

7.3 接口函数

涉及的主要接口包括创建、发送、接收及删除等,具体参数结构参考下图:

接口详情

控制接口

7.4 常用命令

查看消息队列状态:

查看命令

删除消息队列:

删除命令


8 信号量

在共享内存场景中,由于缺乏保护机制,多进程并发访问容易导致数据竞争。信号量正是为了解决这一问题而引入的同步互斥工具。

注:此处侧重理论理解,线程部分的信号量将在后续章节展开。

8.1 概念补充

学习管道时可能对'共享资源'感知不强,但信号量能让我们深刻理解多进程如何访问同一份资源。

  • 共享资源:多个执行流(进程)都能看到的公共资源。
  • 临界资源:被保护起来、一次只允许一个执行流访问的资源。
8.1.1 互斥与同步
  • 互斥:任何时刻只允许一个执行流访问资源(如 ATM 取钱、上厕所)。
  • 同步:多个进程按特定顺序执行(如一个进程等待另一个进程完成)。

互斥 + 同步 + 共享资源 = 临界资源

8.1.2 程序员视角

无论是同步还是互斥,最终都落实到代码层面。例如父子进程同时向 stdout 打印内容,由于 Linux 下'一切皆文件',显示器作为设备文件属于共享资源且未被保护,会导致输出错乱。解决此类问题需要引入同步与互斥机制。

打印错乱示例

8.1.3 临界区

访问公共资源的代码段称为【临界区】,不访问的称为【非临界区】。进入临界区前加锁,离开时解锁,以此保护临界资源。

临界区保护

8.1.4 思维导图

概念总结

8.2 信号量的三个核心问题

学习信号量可借鉴'是什么、为什么、怎么办'的思路。

8.2.1 信号量是什么?

教材常将其译为'信号灯'。它本质上是一种实现同步和互斥的技术,适用于公共资源的整体或局部访问场景。

信号量定义

8.2.2 本质理解

信号量是一个计数器,衡量临界资源的数量。想象成 int count,初始值为资源总数。

计数器本质

8.2.3 实例类比

以电影院为例,座位数即资源上限。买票相当于申请信号量(P 操作),入座即访问资源。若票卖完,后续进程需等待。这体现了对共享资源的预定机制。

买票类比

伪代码逻辑如下:

// 简化示意
if (count > 0) {
    count--;
    // 进入临界区
} else {
    // 等待
}
8.2.4 极端场景

若放映厅只有一个座位,竞争将更激烈,信号量的计数作用更为关键。

单座场景

8.2.5 思维导图

信号量导图

8.2.6 为什么需要信号量?

根本原因是解决多进程访问共享资源时的并发读写冲突。

并发问题

8.2.7 如何实现?

需要了解相关接口:创建 (semget)、操作 (semop)、控制 (semctl)。

  • 创建信号量集:semget 允许创建信号量集合。
  • 删除信号量:使用 semctl 指定 IPC_RMID。
  • 获取信息:semctl 配合 IPC_STAT 可获取创建时间等元数据。

信号量集结构

信号量本质是计数器,操作通常涉及 +1 或 -1。

操作含义

sembuf 结构体是 semop() 调用的核心,包含三个成员:

  • sem_num:指定操作哪个信号量(索引)。
  • sem_op:定义增减值或等待条件。
  • sem_flg:控制阻塞行为与自动撤销。

这三个成员共同决定了信号量如何修改或等待,是实现同步互斥的基础。

以下是一段典型的 P 操作示例代码:

#include <sys/sem.h>

struct sembuf sb;
// 假设已通过 semget() 获得信号量集标识符 semid

sb.sem_num = 0;      // 第 1 个信号量
sb.sem_op = -1;      // 减少 1(P 操作)
sb.sem_flg = SEM_UNDO; // 进程退出时自动还原

if (semop(semid, &sb, 1) == -1) {
    perror("semop");
} else {
    // 成功获取资源,进入临界区
}

注意:SEM_UNDO 的回滚机制较复杂,常规开发中了解即可。此外,信号量的创建与空间开辟是分开的步骤。

8.2.8 实现流程总结

流程总结

目录

  1. 7 消息队列
  2. 7.1 概念说明
  3. 7.2 工作原理
  4. 7.3 接口函数
  5. 7.4 常用命令
  6. 8 信号量
  7. 8.1 概念补充
  8. 8.1.1 互斥与同步
  9. 8.1.2 程序员视角
  10. 8.1.3 临界区
  11. 8.1.4 思维导图
  12. 8.2 信号量的三个核心问题
  13. 8.2.1 信号量是什么?
  14. 8.2.2 本质理解
  15. 8.2.3 实例类比
  16. 8.2.4 极端场景
  17. 8.2.5 思维导图
  18. 8.2.6 为什么需要信号量?
  19. 8.2.7 如何实现?
  20. 8.2.8 实现流程总结

更多推荐文章

查看全部
  • Linux 匿名管道通信:原理、特性与实战代码详解
  • C++ 手写高性能日志模块:基于策略模式实现
  • 6 个 Python 办公自动化技巧:PDF 解析、邮件发送与数据分析实战
  • QClaw 本地 AI 助手部署指南:微信集成与基础配置
  • 滑动窗口算法实战:长度最小的子数组与无重复字符的最长子串
  • 基于 ECharts 与 Flask 的交互式数据可视化应用开发
  • 手写数据库内核组件:单链表分层设计与实现
  • 大疆测试岗实习面试全流程复盘
  • AI Ping 实战:统一接口降低大模型调用成本与复杂度
  • MCP Server 案例:利用 Excel 生成可视化 HTML 报告
  • 使用轻量应用服务器一键部署 Clawdbot AI 智能体
  • Whisper Large v3 模型解析:语音特征提取与处理机制
  • MySQL EXPLAIN 实战:6 种索引失效场景验证与优化
  • Django 日志记录配置与使用详解
  • 飞书 lark-cli 命令行工具与 AI Agent 集成解析
  • Windows 系统 Visual C++ 运行库全生命周期管理方案
  • Docker 安装及基础操作指南
  • Java 中的 char、String、StringBuilder 与 StringBuffer 详解
  • Java 字符串转整数与拼接实战指南
  • CSS Flex 布局基础应用指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online