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

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

Linux 进程间通信进阶主要涵盖消息队列与信号量机制。消息队列作为系统级 IPC,通过有类型数据块实现进程间通信,需使用 key 值标识及特定接口操作。信号量用于解决多进程并发访问共享资源的互斥与同步问题,本质是计数器。通过 P/V 操作控制临界区资源访问,防止数据竞争。了相关概念、原理、接口命令及代码示例,帮助理解操作系统层面的资源调度与保护机制。

星落发布于 2026/3/26更新于 2026/7/528 浏览
Linux 进程间通信进阶:消息队列与信号量

7 ~> 消息队列

7.1 消息队列的概念

这个消息队列是系统层面的概念,不是组件级别的。

所谓的消息队列,就是在操作系统里面维护一个队列结构。

7.2 消息队列的原理

  • 消息队列——操作系统提供的 IPC 结构。

也会存在一个由用户设置的 key 值(A、B 进程都能够看到),约定好的。

双方通过往消息队列里面插入节点来进行通信。

消息队列在内核中也要存在一个描述结构体。

消息队列结构体

消息队列也有自己的结构体,看到自己的键值。

消息队列和共享内存都是系统级的 IPC。

如果这个数据节点只有数据,操作系统怎么区分这是 A 的还是 B 的? 必须保证这种数据块是有类型的数据块!

  • 消息队列是一种一个进程给另一个进程发送有类型数据块的方式!

我们需要的系统调用:

消息队列接口

7.3 消息队列的接口

消息队列接口详情 1

消息队列接口详情 2

7.4 消息队列的一些命令

  • 查看消息队列

查看消息队列

  • 删除消息队列

删除消息队列


8 ~> 信号量

在共享内存那里我们知道,使用共享内存的时候,共享内存没有保护机制,信号量可以保护共享内存。

信号量保护共享内存

  • 在共享内存这里先谈理论部分,在线程那里再谈别的。
  • 这里我们重点理解信号量是什么的问题!

8.1 概念补充

概念补充图

当你学了管道,可能对'看到同一份资源'没有强烈的感觉;但是学了信号量就可以了——

  • 多进程通信,最重要的是让不同的进程看到同一份资源

解决方案:不同的进程看到同一份资源 -> 新的问题也就从这里展开了!

新的解决方案引入新的问题(硬币也有正反、有钱了解决了现在的问题但是又有一大批人来借钱了、……)。

  • 问题:对同一个进程进行访问的时候会出现并发访问出现错误的问题!

比如刚才的两个写端的互相清空覆盖的现象(同时打开两个写端)——互相干扰。

8.1.1 共享资源和临界资源

我们现阶段是处在'并发访问出现错误'的阶段。

  • 我们把多个执行流(进程)能够看到的公共资源叫做共享资源
  • 把被保护起来的资源叫做临界资源。
8.1.2 互斥和同步
  • 任何时刻只允许一个执行流访问资源,就叫做互斥

只允许我一个人访问,比如 ATM 机器取钱、上厕所关门等等——不想被别人打扰,就是互斥访问——

互斥示例

ATM 机就是这个临界资源,有了顺序性,就是同步。

让多个进程执行的时候一定要有顺序,按顺序执行——同步。

一个进程在等另一个进程。

  • 互斥与同步 + 共享资源 = 临界资源(被保护的共享资源)
8.1.3 和程序员有什么关系?

程序员关系图

不管是同步、互斥,共享资源、临界资源,上面这些工作具体和程序员有什么关系?我程序员就是个写代码的啊!

  • 为了更好地理解,再举一个例子

父子进程打印

  • 父子进程打印内容错乱、没有规律,一会儿打父进程的、一会儿打子进程的。

大家有没有遇到过父子进程都往同一个显示器上面打印消息的时候,发生错乱的这种情况?

这是因为 Linux 下一切皆文件,stdout其实是一个共享资源,我们父子进程向它打印的时候,这个共享资源是没有被保护起来,所以会出现这种现象,我们要保护的话需要同步与互斥这种机制。所以并发错乱的问题我们早就遇到过了。

  • Linux 下一切皆文件,显示器也是文件(设备文件),在这里属于共享资源,这里的显示器是没有被保护的(数据不一致,这里先不说),为了防止【错乱】,要通过同步和互斥来保护显示器这个共享资源。

stdout 共享

stdout 保护

为什么突然说这个?

原因分析

8.1.4 临界区

一定要记住,所谓的共享资源,站在程序员的视角,将来程序员也是通过代码访问共享资源的!

未来程序员所写的代码,有的代码是会访问共享资源,同样的,有的代码不会访问共享资源。

  • 把访问公共资源的代码叫做【临界区】,把不访问公共资源的代码叫做【非临界区】。

在进入临界区之前,进行加锁;离开时,解锁。

  • 通过加锁、解锁——写代码的方式要改,把临界资源保护起来

临界区示意图

8.1.5 保护访问公共资源的代码
  • 保护访问公共资源的代码

保护代码

8.1.6 补充概念思维导图

思维导图

8.2 信号量的三个问题

一看到问题,我们就会想到高中语文学习时候的三个问题:

  • 是什么?
  • 为什么?
  • 怎么办?

我们学习信号量的时候也可以迁移这种发问的思想。

8.2.1 (概念)信号量是什么?

很多教材里面喜欢管信号量叫做'信号灯'——被翻译过来的。

  • 信号量:用来实现同步和互斥的一种技术。
  • 场景:公共资源 -> 把公共资源当做整体访问(ATM 机器),也有局部使用(电影院看电影,一个座位)。

信号量概念

8.2.2 信号量的本质
  • 信号量本质:是一个计数器,用来衡量临界资源中,资源数量的计数器,可以想象成一个 int count——计数器就是信号量的本质。

信号量本质

8.2.3 理解

我们基本上没见过电影院放印厅因为座位发生争执的,因为电影院就那么多座位也只会放最多这么多人进来。

座位真正属于你的时候,是什么时候?——买票的时候

只要买到了票,必然有座位。

票卖完了也很正常,说明总票数是一个计数器,本身是有上限的,我们可以通过买票的操作对这个计数器进行减减(--)。

  • 1、买票
  • 2、坐在你的座位上 - 本质上就是你已经开始访问这个资源了

我只要把票买了,这个座位就是属于我了。相当于我提前预定了,其他人不能占我的位置。换言之我只要买了票,就一定会有一个资源属于我。

所以,买票的本质:对共享资源的一种预定机制!

在我们今天来看我们可以把这个放映厅想成内存块。一个个人就是一个个进程。就像我人要买票,每一个进程也需要对应的操作才能访问,也就是先申请信号量,所以我们进入临界区对这个计数器------>P(),走了++,V()。

买票类比

申请信号量这个操作的本质就是对临界区资源进行预定。

我们来写一个不太严谨的伪代码来帮助理解一下:

伪代码

8.2.4 补充故事:如果今天电影院的放映厅里面只有一个座位呢

单座故事

8.2.5 信号是什么的思维导图

信号思维导图

8.2.6 为什么要有信号量?
  • 因为有问题:并发访问 ~> 信号量 ~> 为了解决多进程访问共享资源产生的并发读写问题。

为什么需要信号量

8.2.7 怎么办?
  • 怎么办:我们就来了解一下信号量的一些接口!
  • 怎么设计信号量?
  • 怎么创建信号量?

我们先来看一下信号量的一些接口——

  • 创建信号量:semget

semget

  • 操作系统允许创建信号集

信号集

  • 信号量集

信号量集结构

  • 删除信号量的系统调用

删除信号量

  • 共享内存信号量在操作系统角度是怎么被'先描述再组织'的?

我们先来看看信号量集——

信号量集详解

这个 5 指的是信号量集里面有五个。

  • 信号量本质是个计数器

计数器

  • 对信号量进行操作的时候用 semctl(不光是删除操作,包括获取、删除、……)

semctl

  • 系统提供的枚举类型的结构体传进去就可以处理初始值

枚举结构

获取信号量集的信息,信号量集的创建时间什么的——

获取信息

这个结构体 struct semid_ds 用于描述 System V 信号量集的关联信息。通过它,你可以获得信号量集的创建时间(sem_ctime),同时还能获取以下信息:

struct 成员

  • 怎么保证看到的是同一个信号量集?

唯一标识

  • 信号量这里的 op 和共享内存那里一样,通常是 +1 或者 -1,代表要进行什么操作

操作数

  • sembuf 结构体是 semop() 系统调用用来描述单个信号量操作的核心数据结构。它包含的三个成员 sem_num、sem_op 和 sem_flg 分别决定了操作的对象、操作的类型以及行为标志。下面详细解释每个成员的作用。

这个 sem_num 是什么?

sem_num

sem_op

sem_flg

我们来看一段作为示例的代码片段:

#include <sys/sem.h>
// 假设已经通过 semget() 获得了一个信号量集的标识符 semid
struct sembuf sb;
// 对信号量集索引为 0 的信号量执行 P 操作(获取资源)
sb.sem_num = 0; // 第 1 个信号量
sb.sem_op = -1; // 想要减少 1
sb.sem_flg = SEM_UNDO; // 进程退出时自动还原
if(semop(semid, &sb, 1) == -1){
    perror("semop"); // 错误处理
} else {
    // 成功获取资源,可以进入临界区
}

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

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

最下面这个回滚就不说啦,很麻烦,上面说的了解一下就行。

  • 信号量创建、开辟空间是分开的!
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.1.5 保护访问公共资源的代码
  13. 8.1.6 补充概念思维导图
  14. 8.2 信号量的三个问题
  15. 8.2.1 (概念)信号量是什么?
  16. 8.2.2 信号量的本质
  17. 8.2.3 理解
  18. 8.2.4 补充故事:如果今天电影院的放映厅里面只有一个座位呢
  19. 8.2.5 信号是什么的思维导图
  20. 8.2.6 为什么要有信号量?
  21. 8.2.7 怎么办?
  22. 8.2.8 信号量怎么办的思维导图
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 稳居 TIOBE 编程语言排行榜榜首
  • AI 编程核心实践:自动化生成、低代码与算法优化
  • 基于关键场景辨别算法的两阶段鲁棒微网优化调度 Matlab 代码实现
  • Web 开发基础:前后端概念解析及 F12 Network 调试
  • JVM 运行时数据区域详解:从内存结构到面试考点
  • AI 技术综述与产品经理角色重塑
  • Python 数据统计与清洗实战指南
  • Java 泛型与通配符:从原理到实战应用
  • 基于腾讯云 HAI 与 DeepSeek 快速构建个人网页
  • 基于STM32的智能家居环境监测与控制系统设计
  • Java 面向对象入门:类、对象与封装核心详解
  • OpenClaw 对接 Stable Diffusion:免费 AI 绘画方案
  • Python 人工智能入门学习指南
  • Claude Code 替代方案:OpenCode 搭配 GitHub Copilot
  • 利用闲置小米 9 打造天马 G 复古掌机指南
  • 自行车在线租赁系统设计与实现(SSM 框架)
  • 黑客的四个级别与自学路线中的常见误区
  • 前端团队协作最佳实践
  • Java 设计支持万人并发抢购的秒杀系统方案
  • FastGPT 集成 MCP 协议实现工具增强型智能体构建

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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