zoukankan      html  css  js  c++  java
  • python Condition类(锁)

    Condition(条件变量)通常与一个锁关联。需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。

    不理解锁的,请看上一条随笔。

    Condition():

    • acquire(): 线程锁
    • release(): 释放锁
    • wait(timeout): 线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。
    • notify(n=1): 通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notify()不会主动释放Lock。
    • notifyAll(): 如果wait状态线程比较多,notifyAll的作用就是通知所有线程
    import threading
    import time
    
    # 商品
    product = None
    # 条件变量
    con = threading.Condition(threading.Lock())
    
    
    # 生产者方法
    def produce():
        global product
    
        if con.acquire():
            while True:
                print('我执行了,produce')
                if product is None:
                    product = 'anything'
                    print('produce...',product)
                    print('plock=',con)
                    # 通知消费者,商品已经生产
                    con.notify()
    
                # 等待通知
                con.wait()
                time.sleep(2)
    
    
    # 消费者方法
    def consume():
        global product
    
        if con.acquire():
            while True:
                print('我执行了,consume')
                if product is not None:
                    print('consume...',product)
                    print('clock=',con)
                    product = None
    
                    # 通知生产者,商品已经没了
                    con.notify()
    
                # 等待通知
                con.wait()
                time.sleep(2)
    
    
    t2 = threading.Thread(target=consume)
    t2.start()
    t1 = threading.Thread(target=produce)
    t1.start()
    1、生产者消费者模型
    import threading
    import time
    
    condition = threading.Condition()
    products = 0
    
    class Producer(threading.Thread):
        def run(self):
            global products
            while True:
                if condition.acquire():
                    if products < 10:
                        products += 1;
                        print "Producer(%s):deliver one, now products:%s" %(self.name, products)
                        condition.notify()#不释放锁定,因此需要下面一句
                        condition.release()
                    else:
                        print "Producer(%s):already 10, stop deliver, now products:%s" %(self.name, products)
                        condition.wait();#自动释放锁定
                    time.sleep(2)
    
    class Consumer(threading.Thread):
        def run(self):
            global products
            while True:
                if condition.acquire():
                    if products > 1:
                        products -= 1
                        print "Consumer(%s):consume one, now products:%s" %(self.name, products)
                        condition.notify()
                        condition.release()
                    else:
                        print "Consumer(%s):only 1, stop consume, products:%s" %(self.name, products)
                        condition.wait();
                    time.sleep(2)
    
    if __name__ == "__main__":
        for p in range(0, 2):
            p = Producer()
            p.start()
    
        for c in range(0, 3):
            c = Consumer()
            c.start()
    2、生产者消费者模型
    import threading
     
    alist = None
    condition = threading.Condition()
     
    def doSet():
        if condition.acquire():
            while alist is None:
                condition.wait()
            for i in range(len(alist))[::-1]:
                alist[i] = 1
            condition.release()
     
    def doPrint():
        if condition.acquire():
            while alist is None:
                condition.wait()
            for i in alist:
                print i,
            print
            condition.release()
     
    def doCreate():
        global alist
        if condition.acquire():
            if alist is None:
                alist = [0 for i in range(10)]
                condition.notifyAll()
            condition.release()
     
    tset = threading.Thread(target=doSet,name='tset')
    tprint = threading.Thread(target=doPrint,name='tprint')
    tcreate = threading.Thread(target=doCreate,name='tcreate')
    tset.start()
    tprint.start()
    tcreate.start()
    3、生产者消费者模型
    import threading
     
    def run(n):
        con.acquire()
        print('我执行了',threading.current_thread().name)
        con.wait()
        print("run the thread: %s" %n)
        con.release()
     
    if __name__ == '__main__':
     
        con = threading.Condition()
        for i in range(10):
            t = threading.Thread(target=run, args=(i,))
            t.start()
     
        while True:
            inp = input('>>>')
    
            if inp == 'q':
                break
            con.acquire()
            con.notify(int(inp))
            con.release()
    View Code

    总结

    1、release和wait都有释放锁的作用,不同在于wait后,该子线程就在那里挂起等待,要继续执行,就需要接收到notify或者notifyAll来唤醒线程,而release该线程还能继续执行。

    2、notify和notifyAll的区别在于,notify只能唤醒一个wait,而notifyAll能唤起所有wait。

  • 相关阅读:
    nginx 附件上传不上去 client_max_body_size 设置的太小
    python 1
    NGINX 常用配置
    Linux OOM Killer 保护机制
    MacbookPro接上HDM连接显示器不能上网的解决方法
    python 逻辑运算符 () > not > and > or
    TASSL 服务端 客户端测试代码
    SSL通信双方如何判断对方采用了国密
    C/S boringSSL那点事
    从Chrome源码看浏览器的事件机制
  • 原文地址:https://www.cnblogs.com/hardykay/p/10203628.html
Copyright © 2011-2022 走看看