在Lock和RLock中,一次只允许执行一个线程,但有时我们的要求是一次执行特定数量的线程。
假设我们必须一次允许10个成员访问数据库,而只允许4个成员访问网络连接。为了处理这类需求,我们不能使用Lock和RLock概念,在这里我们应该使用Semaphore 。信号量可用于限制对容量有限的共享资源的访问。它是同步的高级部分。
创建一个信号量对象:
object_name = Semaphore(count)
这里的“计数”是允许同时访问的线程数。 count的默认值为1。
当线程执行acquire()方法时,“ count”变量的值将减少1,每当线程执行release()方法时,“ count”变量的值将增加1。即,无论何时acquire()方法将被称为count变量的值将在任何时候减小 将调用release()方法,“ count”变量的值将增加。
创建信号量对象的方法:
情况1 :
object_name.Semaphore()
在这种情况下,由于默认情况下count变量的值为1,因此仅允许一个线程访问。它与“锁”概念完全相同。
情况2 :
object_name.Semaphore(n)
在这种情况下,一个信号量对象可以一次被n个线程访问。其余线程必须等到释放信号量。
信号量的可执行代码:
Python3
# importing the modules
from threading import *
import time
# creating thread instance where count = 3
obj = Semaphore(3)
# creating instance
def display(name):
# calling acquire method
obj.acquire()
for i in range(5):
print('Hello, ', end = '')
time.sleep(1)
print(name)
# calling release method
obj.release()
# creating multiple thread
t1 = Thread(target = display , args = ('Thread-1',))
t2 = Thread(target = display , args = ('Thread-2',))
t3 = Thread(target = display , args = ('Thread-3',))
t4 = Thread(target = display , args = ('Thread-4',))
t5 = Thread(target = display , args = ('Thread-5',))
# calling the threads
t1.start()
t2.start()
t3.start()
t4.start()
t5.start()
输出:
在上面的示例中,我们首先创建了一个信号量类的实例,其中“ count”的值为3,这意味着信号量对象一次可以被3个线程访问。现在,我们创建了display()方法,该方法将打印线程名称5次。现在我们创建了5个线程,并且现在每当我们调用start()方法时,都允许3个线程访问Semaphore对象,因此一次允许3个线程执行display()方法,但是在此示例中,只要我们执行,我们将获得不规则的输出,因为3个线程一次执行了display()方法。