「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
在 《线程间同步的实现与代码》,已经介绍了线程间同步的方法,并介绍了 Python 中的互斥量(锁) Lock
。在《【Python】多线程之可重入锁》中,又介绍了 Python 中的可重入锁 RLock
。它们都属于库 threading
。这篇文章,我们来看看 threading
中另一种控制线程同步的方法——信号量。
信号量
信号量可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。通常用于那些有明确数量资源的操作。
比如数据库连接池,由于对于同时连接的线程数量有限制,不能超过一定数量。所以当当前连接数量到达一定数量之后,需要连接数据库的线程就需要排队等待,等待之前连接了数据库的线程释放连接之后,才能连接数据库。
Semaphore
Python 中,通过 threading.Semaphore()
获取一个信号量。
semaphore = threading.Semaphore(value= 1)
:创建一个信号量,value
指定了资源的数量,其值必须大于等于0,否则会抛出ValueError
异常semaphore.acquire(blocking=True, timeout=None)
:从信号量获取一个资源- 当资源数量大于等于1时,资源数量减1,并立即返回
True
- 当
blocking
为True
且资源为 0 时,线程被阻塞,直到有其他线程释放资源 - 当
blocking
为False
且资源为 0 时,直接返回False
- 当
timeout
不为None
时,线程最多被阻塞timeout
秒,超时后返回False
- 当资源数量大于等于1时,资源数量减1,并立即返回
semaphore.release()
:释放一个资源semaphore._value
:剩余的资源数量
BoundedSemaphore
threading.BoundedSemaphore()
是一个工厂函数,返回一个新的有界信号量对象。一个有界信号量会确保它当前的值不超过它的初始值。如果超过,会抛出 ValueError
异常。
bsemaphore = threading.BoundedSemaphore(value= 1)
:创建一个信号量,value
指定了资源的数量,其值必须大于等于0,否则会抛出ValueError
异常bsemaphore.acquire(blocking=True, timeout=None)
:从信号量获取一个资源- 参数的意义与
threading.Semaphore()
一致
- 参数的意义与
semaphore.release()
:释放一个资源,释放时会检查当前的资源数量,如果当前资源数量大于等于初始化设定的资源数量,会抛出ValueError
异常。semaphore._initial_value
:初始化时设定的资源数量semaphore._value
:剩余的资源数量