zoukankan      html  css  js  c++  java
  • Python:Day29 信号量、条件变量

    信号量:semaphore

    信号量是用来控制线程并发数的。(理解:虽然GIL任意时刻都只有一个线程被执行,但是所有线程都有资格去抢,semaphore就是用来控制抢的GIL的数量,只有获取了semaphore的线程才有资格去抢GIL,起到了限制线程并发数的作用)

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        def run(self):
            if semap.acquire():
                print(semap)
                print(self.name)
                time.sleep(5)
                semap.release()
    
    
    semap = threading.Semaphore(5)  # 括号内如果没有指定数据,默认为1
    
    thrs = []
    
    for i in range(100):
        thrs.append(MyThread())
    for i in thrs:
        i.start()

    semaphore也是一把锁,这把锁内部有一个计数器,被acquire()的时候-1,release()的时候+1,当计数器为0的时候,其它线程将被阻塞。

    semaphore和RLock都可以被重复获取,也都有计数器,区别是:semaphore是被不同线程获取,而RLock只能被同一线程重复获取。

    条件变量:不仅能实现锁的功能,而且能够实现类似线程间的通信功能

    用于一个标志符来实现线程间通信

    threading.Condition([Lock/Rlock]):锁是可选选项,不传入锁,对象自动创建一个Rlock(0

    wait():条件不满足时调用,线程会释放锁并进入等待阻塞

    notify():条件创造后调用,通知等待池激活一个线程

    notifyAll():条件创造后调用,通知等待池激活所有线程

    import threading
    from random import randint
    import time
    
    
    class Producer(threading.Thread):
        def run(self):
            global L
            while 1:
                lock_con.acquire()
                r = randint(0, 100)
                print(self.name + "已生产" + str(r))
                L.append(r)
                lock_con.notify()
                lock_con.release()
                time.sleep(1)
    
    
    class Consumer(threading.Thread):
        def run(self):
            global L
            while 1:
                lock_con.acquire()
                if len(L) == 0:
                    lock_con.wait()
                print("消费者吃了"+str(L[0]))
                del L[0]
                lock_con.release()
    
    
    if __name__ == '__main__':
        L = []
        lock_con = threading.Condition()
        threads = []
        for i in range(5):
            threads.append(Producer())
        threads.append(Consumer())
        for i in threads:
            i.start()

    要想实现两个线程之间的通信,两个线程用的必须是同一把锁,不然无法起到作用。

    条件同步(Event)

    条件同步和条件变量同步差不多,只是少了锁的功能,因为条件同步设计于不访问共享资源的环境。

    event = threading.Event():条件环境变量,初始值为False

    event.isSet():返回event的状态值
    event.set():设备event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调试。
    event.clear():设置event的状态值为False
    event.wait():如果event的状态值为False时,阻塞线程

     实例1:

    import threading
    import time
    
    
    class Boss(threading.Thread):
        def run(self):
            print("今晚要加班!!!!")
            event.set()
            time.sleep(5)
            print("已经10点了,可以下班了!")
            event.set()
    
    
    class Work(threading.Thread):
        def run(self):
            event.wait()
            print("命苦啊!!!!")
            event.clear()
            event.wait()
            print("oh,yeah!")
    
    
    if __name__ == '__main__':
        event = threading.Event()
        threads = []
        for i in range(3):
            threads.append(Work())
        threads.append(Boss())
        for i in threads:
            i.start()
        for i in threads:
            i.join()

    实例2:红绿灯

    import threading
    import time
    import random
    
    
    def ligth():
        if not event.isSet():
            event.set()
        count = 0
        while 1:
            if count < 10:
                print("this light is green!")
            elif count < 13:
                print("the light is yellow!")
            elif count < 20:
                if event.isSet():
                    event.clear()
                print("the light is red!")
            else:
                count = 0
                event.set()
            time.sleep(1)
            count += 1
    
    
    def car(n):
        while 1:
            time.sleep(random.randrange(10))
            if event.isSet():
                print("car %s is running" % n)
            else:
                print("car %s is waiting for red light..." % n)
    
    
    event = threading.Event()
    Light = threading.Thread(target=ligth)
    Light.start()
    for i in range(3):
        t = threading.Thread(target=car,args=(i,))
        t.start()
  • 相关阅读:
    CSS 3中细线边框如何实现?
    【SPL标准库专题(1)】 SPL简介
    【PSR规范专题(5)】PSR-4 改进后的自动加载规范
    【PSR规范专题(4)】PSR-3 日志接口规范
    【PSR规范专题(3)】PSR-2 代码风格规范
    【PSR规范专题(2)】PSR-1 基本代码规范
    YII框架的依赖注入容器与服务定位器简述
    PHP 反射机制Reflection
    【Apache运维基础(5)】Apache的Rewrite攻略(2)
    【Apache运维基础(4)】Apache的Rewrite攻略(1)
  • 原文地址:https://www.cnblogs.com/sq5288/p/9358062.html
Copyright © 2011-2022 走看看