7. 消息队列
7.1 概念辨析
这里讨论的消息队列是操作系统层面的 IPC 机制,而非应用组件中的中间件。简单来说,它是在内核中维护的一个队列结构,用于进程间传递数据。
7.2 工作原理
消息队列由操作系统提供,通过用户设置的 key 值(A、B 进程约定好)进行标识。双方通过向队列插入节点来通信。内核中会维护一个描述结构体,确保数据块带有类型标识,从而区分不同进程的数据。
核心逻辑是:消息队列是一种一个进程给另一个进程发送有类型数据块的方式!
系统调用主要包括创建、发送、接收和控制操作。
7.3 接口概览
主要涉及以下系统调用:
msgget:创建或获取消息队列。msgsnd:发送消息。msgrcv:接收消息。msgctl:控制消息队列(如删除)。
7.4 常用命令
在终端中,可以使用 ipcs -q 查看当前系统的消息队列信息,使用 ipcrm -q 配合队列 ID 进行删除。
8. 信号量
共享内存虽然高效,但缺乏保护机制。信号量正是为了解决这个问题而引入的,它能对共享资源进行同步和互斥控制。
8.1 核心概念
8.1.1 共享资源与临界资源
多个执行流能看到的公共资源称为共享资源。被保护起来、一次只允许一个访问的资源称为临界资源。
8.1.2 互斥与同步
- 互斥:任何时刻只允许一个执行流访问资源(如 ATM 机取款)。
- 同步:多个进程按特定顺序执行(如一个进程等待另一个进程完成某事)。
互斥 + 同步 + 共享资源 = 临界资源
8.1.3 程序员视角
在 Linux 下,一切皆文件。父子进程同时往 stdout 打印时,由于 stdout 是共享资源且未受保护,输出常会错乱。这需要通过同步与互斥机制来解决。
8.1.4 临界区
访问公共资源的代码段称为临界区。进入前加锁,离开后解锁,以此保护资源。
8.2 信号量的三个问题
学习信号量可以遵循'是什么、为什么、怎么办'的思路。
8.2.1 是什么?
信号量常被翻译为'信号灯',本质是一个计数器,用来衡量临界资源中剩余资源的数量。场景包括公共资源的整体访问(如 ATM)和局部使用(如电影院座位)。
8.2.2 为什么要有?
多进程并发访问共享资源会产生读写冲突。信号量是为了解决这种并发问题而设计的。
8.2.3 怎么办?
我们需要了解信号量的接口来实现创建、操作和删除。
1. 创建信号量集
使用 semget。操作系统允许创建信号量集,包含多个信号量。
2. 操作信号量
使用 semop。通过 sembuf 结构体描述操作:
sem_num:指定操作哪个信号量(索引)。sem_op:定义增减值或等待条件(如 -1 表示 P 操作,+1 表示 V 操作)。sem_flg:控制阻塞行为与自动撤销。
示例代码片段:


