-
threading.Lock
这个锁是不被某个特定线程所拥有的。一个线程获取了锁,之后任何线程尝试着获取锁,都会失败,包括这个获取了锁的线程自己尝试获取锁。
例如,如下代码就会堵塞
import threading
lock = threading.Lock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()
lock.acquire(blocking=True, timeout=-1),返回的为True或者False,分别代表成功和失败。
默认有两个参数,一个是blocking=True,意思是调用方法的时候没有获取到锁,就会堵塞线程,直到获取到锁为止。
import threading
lock = threading.Lock()
print(lock.acquire(blocking=True))
print(lock.acquire(blocking=False))
# output:
# True
# False
另一个参数是timeout=-1,表示等待获取锁的时间,-1表示一直等待。如果超过timeout设定的时间还没有获取到锁就会有获取锁失败
import threading
lock = threading.Lock()
print(lock.acquire(blocking=True))
print(lock.acquire(timeout=1))
# output:
# True
# False
这两个参数设定的时候需要注意,如何设定了timeout为正数,则不能设定blocking=False。因为设定了timeout为正数表明等待设定的时间会阻塞线程,和blocking=False是矛盾的。
-
threading.RLock
这个锁可以由同一个线程获取多次,它由除了locked和unlocked状态之外的owning thread和recursion level的概念组成。从一个已经获取了锁的线程中获取锁,需要调用acquire方法,如果该线程已经有锁,那么立刻返回True。如果需要释放锁,则调用release方法。
注意,acquire()/release()方法成对出现,只有最后一个release()方法才会真正的释放该线程的锁,允许其他线程获取。
参数和threading.Lock一样。。。
示例:该程序不会一直堵塞
import threading
lock = threading.RLock()
print(lock.acquire())
print(lock.acquire())
lock.release()
lock.release()
# output:
# True
# True
-
threading.Condition
threading.Condition拥有比Lock和RLock更加细腻度的控制。该对象除了拥有acquire和release方法外还有如下方法:(下面三个方法在没有调用acquire之后和调用release之前是不能调用的)
- wait交出线程的锁
- notify通知其他线程条件发生变化,但是并不交出锁
- notify_all如果有很多线程,那么使用notify_all
我觉得Condition中的线程主要有三种状态
- 运行状态:该线程获得控制权,正在运行
- 阻塞状态:该线程不可能获得控制权,相当于调用了wait方法,但是没有获得notify通知的线程
- 就绪状态:等待获得控制权的线程,该线程获得控制权就可以运行,获得了notify或者notify_all通知的线程
示例:生产者卖火锅丸子,总共生产10个。每生产五个,消费者才能开始吃。消费者吃完了之后,等待生产者生产丸子。
import threading
import time
class Producer(threading.Thread):
def __init__(self, con):
self.con = con
super().__init__()
def run(self):
# times = 0
global num
self.con.acquire()
for _ in range(10):
print("开始添加丸子")
num += 1
print("火锅里面丸子的个数为:{}".format(num))
time.sleep(1)
if num == 5:
print("火锅里面的丸子已经到达五个, 无法继续添加了")
self.con.notify()
self.con.wait()
# times += 1
self.con.release()
class Consumer(threading.Thread):
def __init__(self, con):
self.con = con
super().__init__()
def run(self):
self.con.acquire()
global num
while num:
print("开始吃啦!")
num -= 1
print("火锅里面的丸子剩余:{}".format(num))
time.sleep(0.5)
if num == 0:
print("火锅里面没有丸子了,快点添加")
self.con.notify()
self.con.wait(6)
self.con.release()
con = threading.Condition()
num = 0
p = Producer(con)
c = Consumer(con)
p.start()
c.start()