社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python并行编程(五):多线程同步之event(事件)实现简易的生产者-消费者模型

若数 • 6 年前 • 507 次点击  
阅读 23

Python并行编程(五):多线程同步之event(事件)实现简易的生产者-消费者模型

什么是事件?

事件在内部管理了一个标志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社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/31549
 
507 次点击