多线程开发 使用Semaphore和BoundedSemaphore对象
一、使用Semaphore和BoundedSemaphore对象
在Python中,可以使用Semaphore和BoundedSemaphore来控制多线程信号系统中的计数器。
1. Semaphore
在Python程序中,类threading.Semaphore是一个信号机,控制着对公共资源或者临界区的访问。信号机维护有一个计数器,指定可同时访问资源或者进入临界区的线程数。每次有一个线程获得信亏机时,计数器为-1。若计数器为0,其他线程就停止访问信号机,,直到另一个线程释放信号机。
在对象 Semaphore中,主要包含了如下所示的内置方法:
(1) aquire(blocking = True,timeout = None): 用于获取Semaphore对象。
- 当使用默认参数(blocking = True)调用本方法时,如果内部计数器的值大于零,将之减一,并返回;如果等于零,则阻塞,并等待其他线程调用release()方法以使计数器为正。这个过程有严格的互锁机制控制,以保证如果有多条线程正在等待解锁,release()调用只会唤醒其中一条线程。唤醒哪一条是随机的。本方法返回True,或无限阻塞。
- 如果blocking = False,则不阻寒,但若获取失败的话,返回False。
- 当设定了timeout参数时,最多阻塞timeout秒,如果超时,返回False。
(2) release():用于释放Semaphore,给内部计数器加1,可以唤醒处于等待状态的线程。
- 在使用计数器对象Semaphore时,调用acquire()会使这个计数器减1,调用release()会使这个计数器加1。
- 计数器的值永远不会小于0,当计数器到0时,再调用acquire()就会阻塞,直到其他线程来调用release()为止。
例如在下面的实例中,演示了使用Semaphore对象运行4个线程的过程。
import threading
import time
def func(semaphore: threading.Semaphore, num):
# 获得信号量,信号量 -1
semaphore.acquire()
print(f"打印信号量:第{num}次")
time.sleep(3)
# 释放信号量,信号量 +1
semaphore.release()
if __name__ == '__main__':
# 初始化信号量,数量为 2
semaphore = threading.Semaphore(2)
# 运行4个线程
for num in range(4):
t = threading.Thread(target=func, args=(semaphore, num))
t.start()
2. BoundedSemaphore
在pyhon程序中,类threading.BoundSemaphore用于实现BoundedSemaphore对象。BoundedSemaphore会检查内部计数器的值,并保证它不会大于初始值,如果超过就会引发一个ValueError错误。在大多数情况下,BoundedSemaphore用于守护限制访问(
但不限于1)的资源,如果semaphore被release()过多次,这意味着存在在bug。
对象BoundedSemaphore会返回一个新的有界信号量对象,一个有界信号量会确保它当前的值不超过它的初始值。如果超过,则引发ValueError,在大部分情况下,信号量用于守护有限容量的资源。如果信号量被释放太多次,它是一种有bug的迹象,如果没有给出,value默认为1。
例如在下面的实例中,演示了使用BoundedSemaphore对象运行4个线程的过程。
import threading
import time
def fun(semaphore, num):
# 获得信号量,信号量减一
semaphore.acquire()
print("thread %d is running." % num)
time.sleep(3)
# 释放信号量,信号量加一
semaphore.release()
# 再次释放信号量,信号量加一,这是超过限定的信号量数目,这时会报错VleE: Semaphore releaged too manytimes
semaphore.release()
if __name__ == '__main__':
# 初始化信号量,教量为2,最多有2个线程获得信号量,信号量不能通过释放而大于2
semaphore = threading.BoundedSemaphore(2)
# 运行4个线程
for num in range(4):
t = threading.Thread(target=fun, args=(semaphore, num))
t.start()
文章来源:https://blog.csdn.net/weixin_47021806/article/details/115535520
标签:BoundedSemaphore,Semaphore,信号量,计数器,线程,semaphore,多线程 From: https://www.cnblogs.com/super-ma/p/17563363.html