活动地址:CSDN21天学习挑战赛
本篇在Python 多线程开发(一)和(二)的基础上,继续讲解Python多线程开发的相关内容,使用Condition 对象。
在Python程序中,使用Condition对象可以在某些事件触发或者达到特定的条件后才处理数据。Python 提供的Conditon对象的目的是实现对复杂线程同步问题的支持。Condition通常与一个锁关联,当需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中的等待阻塞状态,直到另一个线程调用notify()/notifyAlI()通知:得到通知后线程进入锁定池等待锁定。
例如在下面的实例中,演示了使用Condition对象实现一个捉迷藏游戏的过程。假设这个游戏由两个人来玩,Hider藏,Seeker找。游戏的规则如下所示:
(1)游戏开始之后,Seeker 先把自己眼睛蒙上,蒙上眼睛后,就通知Hider。
(2) Hider 接收通知后开始找地方将自己藏起来,藏好之后,再通知Seeker可以找了。
(3) Seeker 接收到通知之后,就开始找Hider.
实例的具体实现代码如下所示。
#------Condition捉迷藏的游戏------
import threading,time
class Hider(threading.Thread):
def __init__(self,cond,name):
super(Hider, self).__init__()
self.cond = cond
self.name = name
def run(self):
time.sleep(1) # 确保先运行Seeker中的方法
self.cond.acquire()
print(self.name + ';我已经把眼睛蒙上了')
self.cond.notify()
self.cond.wait()
print(self.name + ':我找到你了~~')
self.cond.notify()
self.cond.release()
print (self.name + ':我赢了')
class Seeker(threading.Thread):
def __init__(self,cond,name):
super(Seeker, self).__init__()
self.cond = cond
self.name = name
def run (self):
self.cond.acquire()
self.cond.wait() #释放对锁的占用,同时线程挂起在这里,直到被notify并重新占有锁
print (self.name + ':我已经藏好了,你快来找我吧')
self.cond.notify()
self.cond .wait()
self.cond.release()
print (self.name +':被你找到了,哎~~')
cond = threading.Condition ()
seeker = Seeker(cond,'seeker')
hider = Hider(cond,'hider')
seeker.start()
hider.start ()
在上述代码中,Hider 和 Seeker都是独立的个体,在程序中用两个独立的线程来表示。在这个模拟的游戏过程中,两者之间的行为有一定的时序关系,我们通过Condition对象来控制这种时序关系。本实例执行后会输出如下结果:
由此可见,如果想让线程一遍又一遍地重复通知某个事件,最好使用Condition对象来实现。