• 11 并发编程-(线程)-信号量&Event&定时器


    1、信号量(本质也是一把锁)Semaphore模块

    信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,

    信号量同一时间可以有5个任务拿到锁去执行,

    如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,

    这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小

    from threading import Thread,Semaphore,currentThread
    import time,random
    
    def task():
        with sm:
            print(f"{currentThread().getName()} in")
            time.sleep(random.randint(1,3))
    
    if __name__ == '__main__':
        sm = Semaphore(3)
        for i in range(10):
            t = Thread(target=task)
            t.start()
    解析:
    Semaphore管理一个内置的计数器,
    每当调用acquire()时内置计数器-1;
    调用release() 时内置计数器+1;
    计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

    2、Event 线程之间的同步

    线程的一个关键特性是每个线程都是独立运行且状态不可预测。

    如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。

    为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。

    在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。

    一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行

    from threading import Event
    
    event.isSet():返回event的状态值;
    
    event.wait():如果 event.isSet()==False将阻塞线程;
    
    event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
    
    event.clear():恢复event的状态值为False。

    
    
    from threading import Thread,Event,currentThread
    import time
    def conn():
    n=0
    while not event.is_set(): # while not Flase
    if n == 3:
    print(f"{currentThread().getName()} try too many times")
    return
    print(f"{currentThread().getName()} try {n}")
    event.wait(0.5)
    n += 1
    print(f"{currentThread().getName()} is connected")
    def check():
    print(f"{currentThread().getName()} is connected")
    time.sleep(5) # sleep(5)时间超过了wait(0.5)的时间
    event.set() # 设置event的状态为True,

    if __name__ == '__main__':
    event = Event()
    for i in range(3):
    t = Thread(target=conn)
    t.start()
    t2 = Thread(target=check)
    t2.start()

    Thread-1 try 0
    Thread-2 try 0
    Thread-3 try 0
    Thread-4 is connected # 程序中是sleep(5)才 event.set()
    Thread-1 try 1
    Thread-2 try 1
    Thread-3 try 1
    Thread-2 try 2
    Thread-3 try 2
    Thread-1 try 2
    Thread-2 try too many times
    Thread-1 try too many times
    Thread-3 try too many times

    3、定时器

     

    3.1、简单版本:

    from threading import Timer
    def hello():
        print('hello word')
    t = Timer(1,hello)
    t.start()

    3.2、每个一定时间发送验证码

    import string,random
    from threading import Timer
    class code:
        def __init__(self):
            self.make_cache()
    
    
        def make_cache(self,interval=20):
            # interval 时间间隔 每个秒自动发送新的验证码
            self.cache = self.make_code
            print(self.cache)
            self.t = Timer(interval,self.make_cache)
            self.t.start()
    
        def check(self):
            while True:
                msg = input('请输入你的验证码>>').strip()
                if msg == self.cache:
                    print('True')
                    self.t.cancel()
                    break
    
        @property
        def make_code(self):
            s = ''.join(random.sample(string.ascii_letters + string.digits, 3))
            ran1 = random.randint(0,9) # randint()头尾都包括
            ran2 = chr(random.randint(65,90))# 大写
            ran3 = chr(random.randint(97,122))# 小写
            res =''.join([str(ran1),str(ran2),str(ran3)])
            res = ''.join([res,s]) # join是把序列转化为 字符串
            return res
    if __name__ == '__main__':
        obj = code()
        obj.check()

    6Mr9iX
    请输入你的验证码>>6Mr9iX
    True

  • 相关阅读:
    sem_timedwait
    netty
    嵌入式系统设计师
    新知识点
    20228
    20227
    mdbook
    optparse模块使用
    TiDB集群销毁删除
    configparser模块的使用
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9734442.html
Copyright © 2020-2023  润新知