python threading/lock&Rlock&condition 锁

threading.RLock和threading.Lock
  在threading模块中,定义两种类型的琐:threading.Lock和threading.RLock。它们之间有一点细微的区别,通过比较下面两段代码来说明:
  

import threading  
lock = threading.Lock() #Lock对象  
lock.acquire()  #获取锁
lock.acquire()  #产生了死琐。  
lock.release()  #释放锁
lock.release()  
import threading  
rLock = threading.RLock()  #RLock对象  
rLock.acquire()  
rLock.acquire() #在同一线程内,程序不会堵塞。  
rLock.release()  
rLock.release()  

这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。
threading.Condition
  可以把Condiftion理解为一把高级的琐,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题。threadiong.Condition在内部维护一个琐对象(默认是RLock),可以在创建Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire, release方法,其含义与琐的acquire, release方法一致,其实它只是简单的调用内部琐对象的对应的方法而已。Condition还提供了如下方法(特别要注意:这些方法只有在占用琐(acquire)之后才能调用,否则将会报RuntimeError异常。):
  Condition.wait([timeout]):
  wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。
Condition.notify():
  唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。
Condition.notify_all()
Condition.notifyAll()
  唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。

 现在写个捉迷藏的游戏来具体介绍threading.Condition的基本使用。假设这个游戏由两个人来玩,一个藏(Hider),一个找(Seeker)。游戏的规则如下:1. 游戏开始之后,Seeker先把自己眼睛蒙上,蒙上眼睛后,就通知Hider;2. Hider接收通知后开始找地方将自己藏起来,藏好之后,再通知Seeker可以找了; 3. Seeker接收到通知之后,就开始找Hider。Hider和Seeker都是独立的个体,在程序中用两个独立的线程来表示,在游戏过程中,两者之间的行为有一定的时序关系,我们通过Condition来控制这种时序关系。
#---- 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() #b      
        print self.name + ': 我已经把眼睛蒙上了'  
        self.cond.notify()  
        self.cond.wait() #c      
                         #f   
        print self.name + ': 我找到你了 ~_~'  
        self.cond.notify()  
        self.cond.release()  
                            #g  
        print self.name + ': 我赢了'   #h  

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()    #a    #释放对琐的占用,同时线程挂起在这里,直到被notify并重新占  
有琐。  
                            #d  
        print self.name + ': 我已经藏好了,你快来找我吧'  
        self.cond.notify()  
        self.cond.wait()    #e  
                            #h  
        self.cond.release()   
        print self.name + ': 被你找到了,哎~~~'  

cond = threading.Condition()  
seeker = Seeker(cond, 'seeker')  
hider = Hider(cond, 'hider')  
seeker.start()  
hider.start()  

你可能感兴趣的:(python)