条件变量condition:用于复杂的线程间同步,是线程中最复杂的同步锁
光用lock是不够的,因为在同一个线程内刚release一个lock,就被本线程内的其他lock,acquire到,那就无法实现多线程的协同操作了
import threading
# class XiaoAi(threading.Thread):
# def __init__(self,lock):
# super().__init__(name="小爱")
# self.lock = lock
# def run(self):
# self.lock.acquire()
# print("{}:在".format(self.name))
# self.lock.release()
#
# self.lock.acquire()
# print("{}:好啊".format(self.name))
# self.lock.release()
# class TianMao(threading.Thread):
# def __init__(self,lock):
# super().__init__(name="天猫精灵")
# self.lock = lock
# def run(self):
# self.lock.acquire()
# print("{}:小爱同学".format(self.name))
# self.lock.release()
#
# self.lock.acquire()
# print("{}:我们来对古诗吧".format(self.name))
# self.lock.release()
# if __name__=="__main__":
# lock = threading.Lock()
# xiaoai = XiaoAi(lock)
# tianmao = TianMao(lock)
#
# tianmao.start()
# xiaoai.start()
通过condition完成协同读诗
Condition内部已经实现了Lock的acquire和release
wait函数可以等待某个函数的通知,notify是通知调用了wait的线程启动。这就类似于Scratch里边的广播和接收消息
from threading import Condition
class XiaoAi(threading.Thread):
def __init__(self,lock):
super().__init__(name="小爱")
self.condition = condition
def run(self):
with self.condition:
self.condition.wait()
print("{}:在".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:好啊".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:君住长江尾".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:共饮长江水".format(self.name))
self.condition.notify()
self.condition.wait()
class TianMao(threading.Thread):
def __init__(self,condition):
super().__init__(name="天猫精灵")
self.condition = condition
def run(self):
with self.condition:
print("{}:小爱同学".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:我们来对古诗吧".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:我住长江头".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:日日思君不见君".format(self.name))
self.condition.notify()
if __name__=="__main__":
condition = threading.Condition()
xiaoai = XiaoAi(condition)
tianmao = TianMao(condition)
启动顺序很重要,先启动开头就是wait的线程,再去启动其他线程
xiaoai.start()
tianmao.start()
当调用wait时,就会先获得一把锁,然后放入一个列表里。
condition有两层锁,一把底层锁,会在调用wait方法时释放,因为with是需要一把底层锁才能进来的。所以调用wait时,释放底层锁,其他使用了with语句的线程才能获取底层锁
另外的锁,会在每次调用wait时,会获取一把锁并放入condition的_waiters列表里,也就是等待队列中,等待notify方法的唤醒