美文网首页
Python并行编程(五):多线程同步之event(事件)实现简

Python并行编程(五):多线程同步之event(事件)实现简

作者: 若数 | 来源:发表于2019-04-12 21:28 被阅读0次

    什么是事件?

    事件在内部管理了一个标志Flag,如果Flag值为 False,那么线程在执行event.wait方法时就会阻塞等值直到Flag值为True,该线程便会顺利执行,而Flag的值是通过event.set()event.clear()设定的:

    • set(): 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态。

    • clear(): 将标志设为False

    • wait(timeout): 如果标志为True将立即返回,否则阻塞线程至等待阻塞状态,等待其他线程调用set()

    • isSet(): 获取内置标志状态,返回TrueFalse

    而Event其实就是一个简化版的 Condition。Event没有锁,无法使线程进入同步阻塞状态,所以当个多个线程处于wait状态时,一旦标志位Flag变为真时,这些线程便会 “同时” (GIL锁的原因,假装在同时执行)执行。

    简单的生产者-消费者模型

    通过事件,我们也可以实现一个简单的生产者-消费者模型:

    
    import threading
    import random
    import time
    
    # 假定商品序号
    goods = 0
    
    # 定义一个事件
    event = threading.Event()
    
    def consumer():
    
        time.sleep(0.5)
        print(threading.currentThread().getName() + ' consumer is wait for goods.')
    
        # 等待事件,进入阻塞状态
        event.wait()
    
        print(threading.currentThread().getName() + ' consumer gets the goods: {}\n'.format(goods))
    
    def producer():
        global goods
        time.sleep(1)
        goods = random.randint(1, 11)
        print('producer makes the goods: {}\n'.format(goods))
        time.sleep(1)
        # Flag --> True
        event.set()
    
    if __name__ == "__main__":
        thread_consumer1 = threading.Thread(target=consumer) 
        thread_consumer2 = threading.Thread(target=consumer) 
        thread_producer = threading.Thread(target=producer) 
    
        thread_consumer1.start()
        thread_consumer2.start()
        thread_producer.start()
    
        thread_consumer1.join()
        thread_consumer2.join()
        thread_producer.join()
    
        print('consumer-producer example end.')
    
    

    运行截图如下:


    运行结果

    我们可以看到,两个消费者都在阻塞等待商品的生产,而一旦生产者通知商品生产成功(event.set() --> Flag=True),消费者们便都会得到该商品,这样看来,event 看似就是condition的简化版本,只是没了锁,线程们不能同步阻塞对共享资源的访问。

    相关文章

      网友评论

          本文标题:Python并行编程(五):多线程同步之event(事件)实现简

          本文链接:https://www.haomeiwen.com/subject/agmhwqtx.html