【Python】多线程之信号量与有界信号量

285 阅读2分钟

「这是我参与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
    • blockingTrue 且资源为 0 时,线程被阻塞,直到有其他线程释放资源
    • blockingFalse 且资源为 0 时,直接返回 False
    • timeout 不为 None 时,线程最多被阻塞 timeout 秒,超时后返回 False
  • 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 :剩余的资源数量