Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
什么是锁?
锁是一种同步机制,用于控制多个线程对共享资源的访问。当一个线程获取一把锁时,其它线程便不能再获取该锁。只有当该线程释放锁之后,其它线程才能获取该锁。
互斥锁
互斥锁使用Lock对象实现,当一个线程和另一个线程尝试获取同一个锁时,其中一个线程会被阻塞,直到该锁被释放。
以下是互斥锁的示例代码:
import threading
num = 0
lock = threading.Lock()
def add_num(lock):
global num
lock.acquire()
for i in range(1000000):
num += 1
lock.release()
t1 = threading.Thread(target=add_num, args=(lock,))
t2 = threading.Thread(target=add_num, args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print(num) # 结果为2000000
在上述代码中,使用了Lock对象实现互斥锁,当一个线程获取到锁之后,另一个线程会被阻塞,直到该线程释放锁。
递归锁
递归锁是互斥锁的变种,它允许同一线程多次获取该锁,而不会被阻塞。并且在同一个线程使用递归锁时,需要释放相应次数的锁才能将该锁释放。
以下是递归锁的示例代码:
import threading
num = 0
lock = threading.RLock()
def add_num(lock):
global num
lock.acquire()
for i in range(10):
lock.acquire()
num += 1
lock.release()
lock.release()
t1 = threading.Thread(target=add_num, args=(lock,))
t2 = threading.Thread(target=add_num, args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print(num) # 结果为200
在上述代码中,使用了RLock对象实现递归锁,当线程多次获取该锁时,不会被阻塞。在释放锁时,需要按照获取锁的次数进行释放。
信号量
信号量是一种计数器,用于控制多个线程对资源的访问。当信号量的计数器为0时,线程将会被阻塞,直到其它线程释放资源并增加了信号量。
以下是信号量的示例代码:
import threading
num = 0
semaphore = threading.Semaphore(1)
def add_num(semaphore):
global num
semaphore.acquire()
for i in range(1000000):
num += 1
semaphore.release()
t1 = threading.Thread(target=add_num, args=(semaphore,))
t2 = threading.Thread(target=add_num, args=(semaphore,))
t1.start()
t2.start()
t1.join()
t2.join()
print(num) # 结果为2000000
在上述代码中,使用了Semaphore对象实现信号量,当信号量的计数器为0时,线程将会被阻塞。
事件
事件是一个内部标志,用于协调多个线程之间的操作。当一个线程等待一个事件时,在其它线程设置该事件之前,它将一直被阻塞。当一个线程设置了一个事件后,所有等待该事件的线程都将被唤醒继续执行。
以下是事件的示例代码:
import threading
event = threading.Event()
def wait_event():
print("start wait event")
event.wait()
print("event is set")
def set_event():
print("start set event")
event.set()
t1 = threading.Thread(target=wait_event)
t2 = threading.Thread(target=set_event)
t1.start()
t2.start()
t1.join()
t2.join()
在上述代码中,使用了Event对象实现事件,线程在等待事件时,会被阻塞,直到其它线程设置了该事件,它才会继续执行。
总结
本文介绍了Python中的四种锁机制:互斥锁、递归锁、信号量、事件。这些机制可以有效避免多线程程序中的资源竞争和死锁等问题。在实际使用中,需要根据不同的场景选择不同的锁机制,在提高程序效率的同时,保证程序安全。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多线程操作之互斥锁、递归锁、信号量、事件实例详解 - Python技术站