LINUX15--进程间的通信-信号量
12.3信号量
在Linux中级开发中,信号量是进程间通信(IPC)的重要同步机制。下面我将详细总结信号量的核心知识点,帮助你全面掌握这一关键技术。
12.3.1信号量基本概念
信号量的本质
信号量是一种特殊的计数器,主要用于实现进程间的互斥与同步。它本身不用于传输数据,而是作为保护机制来控制对共享资源的访问。
核心特性
- 原子操作:P操作和V操作是原子性的,执行期间不会被中断
- 资源计数:信号量的值表示当前可用资源的数量
- 进程阻塞:当资源不足时,进程会被挂起等待
12.3.2 信号量工作原理
PV操作原语:
信号量的核心是两种原子操作:
P操作(等待/申请资源)
- 将信号量值减1
- 如果信号量值 ≥ 0,进程继续执行
- 如果信号量值 < 0,进程被阻塞,放入等待队列
V操作(发送/释放资源)
- 将信号量值加1
- 如果有进程在该信号量上等待,则唤醒一个进程
- 如果没有进程等待,信号量值保持正值
信号量值的含义
- 值 > 0:表示可用资源的数量
- 值 = 0:表示无可用资源,但无进程等待
- 值 < 0:其绝对值表示等待该资源的进程数量
12.3.3 信号量系统调用
1. semget - 创建/获取信号量
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);
参数说明:
- key :信号量键值,可以使用 ftok() 生成或使用 IPC_PRIVAT E
- nsems :需要创建的信号量数量
- semflg :权限标志,如 IPC_CREAT | 0666
2. semop - 信号量操作
int semop(int semid, struct sembuf *sops, unsigned nsops);
sembuf结构体
struct sembuf {short sem_num; // 信号量编号short sem_op; // 操作类型:-1(P操作), 1(V操作)short sem_flg; // 标志位,如SEM_UNDO};
3. semctl - 信号量控制
int semctl(int semid, int semnum, int cmd, ...);
常用命令:
- SETVAL :设置信号量的值
- GETVAL :获取信号量的值
- IPC_RMID :删除信号量集
12.3.4 信号量的三种应用场景
1. 进程互斥(Mutex)
保证同一时刻只有一个进程可以访问临界资源。
实现步骤:
// 初始化信号量为1sem_t mutex = 1;// 进程进入临界区前P(mutex);// 临界区代码V(mutex);
2. 进程同步
控制进程的执行顺序,保证"一前一后"执行。
实现步骤:
// 初始化信号量为0sem_t sync = 0;// 前驱进程// 执行代码...V(sync); // 发送信号// 后继进程P(sync); // 等待信号// 执行代码...
3. 前驱关系
实现复杂的进程执行顺序控制。
12.3.5 实际代码示例
互斥信号量示例
#include <sys/sem.h>#include <stdio.h>// 定义联合体(某些Linux版本需要)union semun {int val;struct semid_ds *buf;unsigned short *array;};int main() {int semid;key_t key = 1234;// 创建信号量semid = semget(key, 1, IPC_CREAT | 0666);// 初始化信号量为1(互斥信号量)union semun arg;arg.val = 1;semctl(semid, 0, SETVAL, arg);// P操作struct sembuf p = {0, -1, SEM_UNDO};semop(semid, &p, 1);// 临界区代码printf("进程进入临界区\n");// V操作struct sembuf v = {0, 1, SEM_UNDO};semop(semid, &v, 1);return 0;}
使用注意事项
1. 信号量初始化:信号量创建后必须正确初始化,否则其值是不确定的。
2. SEM_UNDO标志:使用 SEM_UNDO 标志可以确保进程异常终止时,信号量值能够恢复,避免资源死锁。
3. 错误处理:所有信号量操作都应该检查返回值,确保程序的健壮性。
4. 资源清理:使用完毕后要及时删除信号量,防止资源泄漏。
12.3.6 信号量在系统中的应用
信号量在实际系统中有着广泛的应用:
- 打印机管理:确保多个进程不会同时使用打印机
- 共享内存保护:保护多个进程对同一块共享内存的访问
- 文件操作同步:保证对文件的互斥访问
- 生产者-消费者问题:协调生产者和消费者的速度
12.3.7总结
信号量是进程间通信中最重要的同步机制,具有以下核心特点:
- 核心功能:实现进程间的互斥与同步,保护临界资源
- 原子操作:P/V操作是不可分割的原子操作
- 灵活应用:通过不同的初始值实现互斥、同步等不同功能
- 系统级支持:属于System V IPC机制,由内核保证其正确性
掌握信号量的使用对于开发复杂的多进程应用程序至关重要,特别是在需要精确控制进程执行顺序和保护共享资源的场景中。