信号量机制与实现详解
源码路径:
rk3588/kernel-6.1/ipc/sem.c
文档目录:linuxDoc/ipc/
目录
一、原理
System V 信号量以 信号量数组(semaphore array) 为单位:
semget创建/打开,返回 semidsemop/semtimedop对数组中一个或多个成员做 P/V(sem_op含sem_num、sem_op、sem_flg)semctl:GETVAL/SETVAL、GETPID、IPC_RMID、SEM_UNDO 等
语义:FIFO 排队(非严格防饥饿);支持 原子多操作(同一 semop 内多个 sembuf)。
二、数据结构
| 结构 | 说明 |
|---|---|
struct sem_array |
含 kern_ipc_perm,数组 sem[] |
struct sem |
semval、修改者 pid、等待队列 |
struct sem_queue |
阻塞的 semop 请求 |
struct sem_undo |
进程退出时回滚调整(CLONE_SYSVSEM 影响 per-thread/per-process) |
三、实现要点(sem.c 文件头注释)
| 主题 | 实现 |
|---|---|
| 扩展性 | 每 数组 独立锁;数组间无全局锁 |
| 唤醒 | waker 完成全部工作,被唤醒任务可无锁返回(wake_q) |
update_queue |
成功 semop 后扫描等待队列,尽量满足后续操作 |
| UNDO | 每进程每数组懒分配 undo 向量,退出时限 SEMVMX |
| 快速路径 | sem_lock() 对部分读路径优化(见源码 sem_lock) |
sysctl(每 ipc_namespace):kernel.sem 四元组 SEMMSL SEMMNS SEMOPM SEMMNI。
四、系统调用
| syscall | 功能 |
|---|---|
semget |
创建/查找 |
semop |
semtimedop 超时为 NULL |
semtimedop |
纳秒级超时 |
semctl |
控制 / 统计 SEM_STAT SEM_INFO |
旧 ipc() 在 syscall.c 中转发 SEMOP/SEMGET/SEMCTL。
五、调试
1 | ipcs -s |
常见问题:EIDRM(数组已删)、EAGAIN(IPC_NOWAIT)、undo 耗尽。
附录
- 行数:约 2400+(
sem.c为 ipc 最大单文件之一)
相关:01 公共框架
正在加载留言…