Python 信号量介绍
什么是信号量
信号量(Semaphore)是一种用于控制并发数量的同步工具。
可以把它理解成“有限数量的通行证”:
- 有通行证时,任务可以继续执行。
- 没有通行证时,任务需要等待。
- 任务执行完后,需要归还通行证。
在 Python 中,信号量常用于限制多个线程或协程同时进入某段关键逻辑。
基本原理
信号量内部维护一个计数器。
-
acquire():申请一个资源,计数器减 1。 -
release():释放一个资源,计数器加 1。 - 当计数器为 0 时,新的任务会阻塞等待。
sequenceDiagram
participant A as 任务A
participant S as 信号量
participant B as 任务B
Note over S: 初始计数 = 1
A->>S: acquire()
S-->>A: 获取成功,计数变为 0
A->>A: 访问共享资源
B->>S: acquire()
S-->>B: 计数为 0,进入等待
A->>S: release()
S-->>B: 唤醒等待任务,计数仍由任务B占用
B->>B: 访问共享资源
B->>S: release()
Note over S: 计数恢复为 1
状态变化
信号量的状态主要由两个部分组成:
- 当前可用计数。
- 正在等待的任务队列。
当任务调用 acquire() 时:
- 如果计数大于 0,说明还有可用资源,任务可以继续执行,计数减 1。
- 如果计数等于 0,说明资源已经被占满,任务会进入等待状态。
当任务调用 release() 时:
- 如果有任务正在等待,信号量会唤醒其中一个等待任务。
- 如果没有任务等待,计数加 1,表示多了一个可用资源。
所以,信号量并不是直接管理资源本身,而是通过计数器管理“允许同时进入的任务数量”。
机制特点
信号量有几个重要特点:
- 它控制的是并发数量,不是任务执行顺序。
- 它依赖
acquire()和release()成对出现。 - 它的初始计数决定了最多允许多少个任务同时进入。
- 它通过等待队列保存暂时无法继续执行的任务。
总结
信号量的本质是一个带等待能力的计数器。
它的核心思想很简单:先申请,后执行,最后释放。