Linux -- 信号量
信号量⭐同步与互斥核心1. 作用解决进程 / 线程同步、互斥问题保护临界资源同一时间只允许一个进程访问2. 本质受保护的整数计数器操作是原子性的不可中断3. 两种信号量二值信号量0/1互斥锁计数信号量控制资源并发数4. PV 原语⭐P 操作proberen-1申请资源信号量 ≥ 0继续执行信号量 0阻塞等待V 操作verhogen1释放资源信号量 0继续执行信号量 ≤ 0唤醒等待队列中的一个进程5. 核心概念临界资源同一时刻只允许一个进程访问的资源临界区访问临界资源的代码段6.信号量 API头文件#include sys/sem.h1.semget创建 / 获取信号量集int semget(key_t key, int nsems, int semflg);nsems信号量集中信号量的个数flagIPC_CREAT | IPC_EXCL | 06002. semctl初始化 / 删除信号量int semctl(int semid, int semnum, int cmd, ...);SETVAL设置初始值IPC_RMID删除整个信号量集必须自定义共用体union semun { int val; struct semid_ds *buf; unsigned short *array; };3. semop执行 PV 操作int semop(int semid, struct sembuf *sops, size_t nsops);struct sembuf { unsigned short sem_num; // 信号量下标 short sem_op; // -1P, 1V short sem_flg; // SEM_UNDO异常退出自动恢复 };7.封装好的信号量工具// sem.h #pragma once void sem_init(); void sem_p(int n); void sem_v(int n); void sem_destroy();// sem.c #include stdio.h #include stdlib.h #include sys/sem.h union semun { int val; struct semid_ds *buf; unsigned short *array; }; int semid 0; void sem_init() { semid semget((key_t)666, 2, IPC_CREAT | IPC_EXCL | 0600); if (semid -1) { semid semget((key_t)666, 0, 0600); return; } union semun a; int arr[2] {1, 0}; for (int i 0; i 2; i) { a.val arr[i]; semctl(semid, i, SETVAL, a); } } void sem_p(int n) { struct sembuf buf {n, -1, SEM_UNDO}; semop(semid, buf, 1); } void sem_v(int n) { struct sembuf buf {n, 1, SEM_UNDO}; semop(semid, buf, 1); } void sem_destroy() { semctl(semid, 0, IPC_RMID); }