Python中的semaphores
在本指南中,我们将学习如何使用信号灯处理Python中的多线程。如何对线程和受限制的资源进行同步访问?
信号灯
一个同步控制器就是一个信号灯。Semaphore为线程提供对有限数量资源的同步访问。
一个semaphore可以被看作是一个变量,代表现在有多少资源可用。
例如,商场中作为信号灯的停车场,在某一层有几个空位。
semaphore的值必须大于或小于可用资源。acquire
和release
的操作与信号灯有关。
当用于同步的资源之一被一个线程 “获得 “时,semaphore的值会减少。当一个同步资源被线程 “释放 “时,semaphore的值会增加。
Python中的信号灯
Python对信号灯概念的实现使用了来自threading
模块的一个类。Semaphore
是这个类的名字。
一个acquire()
和release()
函数都包含在Semaphore
类中,同时还有一个函数构造器。
如果semaphore计数超过0,则使用acquire()
函数来降低计数。如果不是,它将阻塞,直到计数大于0。
坐在信号灯上的一个线程通过使用release()
函数被唤醒,这也会增加信号灯的计数。现在我们来了解一下信号灯的语法。
object_name = threading.Semaphore(count)
在上面的语法中,Semaphore
类对象是由object_name
表示的。
允许一次访问的线程数由Semaphore
类的count
参数指定。这个参数的默认值是1。
每当一个线程使用acquire()
函数时,count
参数的值就减少1。每当一个线程使用release()
函数时,count
参数的值就会增加1。
根据这一声明,无论何时我们调用acquire()
方法,count
参数的值都会减少;然而,当我们调用release()
函数时,count
参数的值将会增加。看一下下面的代码。
#import threading module
import threading
#creating instance of semaphore
sema = threading.Semaphore(1)
def test():
#appling semaphore
print(f"Value Of Semaphore --> {sema._value}")
sema.acquire()
print(f"acquired lock --> {threading.current_thread().name}")
print(f"Value Of Semaphore --> {sema._value}")
print(f"release lock --> {threading.current_thread().name}")
sema.release()
print(f"Value Of Semaphore --> {sema._value}")
#initializing threads
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t3 = threading.Thread(target=test)
#executing threads
t1.start()
t2.start()
t3.start()
如果count
被设置为1,线程将被同步,如上面的代码。如果我们看一下上面代码的输出,我们会发现,将是第一和第二线程,然后第三线程将可以访问acquire
和release
之间的代码。
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
Value Of Semaphore --> 0
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
如果你将count
的值从1改为2,你将允许两个线程同时访问受限的代码。所以,输出结果将是不同的。
Value Of Semaphore --> 2
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 2
注意,信号灯释放线程的时间是基于你的设备的速度,每次都会有所不同。你可以通过改变semaphore实例中count
的值来测试上面的代码。