Python3.x:threading module Event及队列queue

Event

记得之前说过线程可以对同一进程下的其他线程进行一定程度上的控制,而这里的Event就实现了这一点

Event就相当于一个全局的标志变量,提供了一些方法,可以在各个线程中修改这个标志变量而不需要声明全局变量,先看看Event的几个常用方法

event = threading.Event()  # 生成Event实例
event.set()  # 设置存在,即相当于设置为True
event.clear()  # 设置清空,即相当于设置为false
event.is_set()  # 检测是否存在,存在返回True
event.wait()  # 检测是否设置存在,如果未设置,则程序一直阻塞

然后我们通过一个简单的红绿灯小程序来看一下如何使用Event

import threading
import time

# 生成Event实例
event = threading.Event()


# 先写红绿灯方法
def light():
    # 进入循环红绿灯一直规律切换
    while True:
        # 设置存在,进入绿灯状态
        event.set()
        # 打印绿灯行
        print('\033[42;1m green light and go!\033[0m')
        # 设置时间间隔5秒
        time.sleep(5)
        # 清空设置,进入红灯状态
        event.clear()
        # 打印红灯停
        print('\033[41;1m red light and stop!\033[0m')
        # 红灯间隔5秒
        time.sleep(5)


# 定义汽车车方法
def car(name):
    # 这里进入循环因为需要一直不停检测设置的Event实例
    while True:
        # 判断是否设置,如果设置则为绿灯则车辆行驶
        if event.is_set():
            # print(event.is_set())
            print('%s is running' % name)
            time.sleep(1)
        else:
            # 否则则为红灯进入等待状态,使用event.wait()阻塞程序检测是否进入绿灯状态
            print('%s is waiting the green light on ...' % name)
            event.wait()
            print('turn on!')


if __name__ == '__main__':
    l = threading.Thread(target=light)
    car1 = threading.Thread(target=car, args=('长安奔奔',))
    car2 = threading.Thread(target=car, args=('甲壳虫',))
    l.start()
    car1.start()
    car2.start()

Event的用法比较简单,这里稍微注意一下两个while就行了

队列queue

怎么理解队列呢?队列就好比一个容器,一个存放数据或者其他东西的容器,有人可能会问那直接用列表不就好了,确实队列跟列表有很多的相似之处,都有顺序性,但是队列拿出一个数据之后这个数据就没有了,而列表所谓的拿出数据只是copy了一份数据,也就是说列表是单纯的存储了数据,而队列就好像真实存在的一个排好队的队伍,至于其他的优点,在你使用了之后会有更深的了解

import queue
q = queue.Queue(maxsize=0)  # 生成先入先出队列实例,有一个参数maxsize设置队列大小,默认是没有大小的,可以一直放数据
q = queue.LifoQueue(maxsize=0)  # last in first out:生成后入先出队列实例,比如货架上的东西后来放上去的在最外面会被人先拿走
q = queue.PriorityQueue(maxsize=0)  # 优先级队列,可以设置优先级来实现排序,这里存入的为元组类型:优先级(数字,小的数字优先级高)对应放入的东西
q.put()  # 放入元素,还有block参数和timeout参数,block参数设置是否阻塞,默认为True,就是说当一个队列最大元素个数为20的话如果你放入第21个则程序会阻塞,timeout设置阻塞时间
q.get()  # 取出元素,跟put有同样的参数,不过是如果取出的队列里面没有元素了才会触发,然后进入等待有人往队列里面放元素
q.put_nowait()  # 无阻塞直接抛出异常等价q.put(block=False)
q.get_nowait()  # 无阻塞直接抛出异常等价q.get(block=False)
q.qsize()  # 返回队列q当前元素个数,这里注意不是队列q的最大元素个数

下面来看看如何使用


先入先出

后入先出

优先级队列

设置大小1放入两个之后阻塞

设置不阻塞直接抛出错误Full

get方法的阻塞与不阻塞设置方法与上面类似


也可以使用get_nowait/put_nowait方法设置不阻塞,这里队列为空了,再取出直接抛出Empty错误

接下来我们就用队列和多线程实现我们以后也会经常用到的生产者消费者模型:

首先理解一下生产者消费者模型:

在这个模型中,我理解划分为三个部分,生产者、消费者和中介容器,生产者和消费者不直接通信,而是通过阻塞队列通信,也就是这个容器,生产者只在容器未满时生产,容器满的时候阻塞生产者的生产;消费者只在容器不为空的时候消费,容器空了之后阻塞消费者消费;这个容器的作用就是平衡协调生产和消费的关系

import threading
import queue
import time

# 生成队列容器
q = queue.Queue()


# 生产者
def producer():
    # 计数方式防止生产过多
    count = 1
    # 进入生产循环
    while True:
        # 判断队列中商品个数是否小于10,小于10则生产,否则阻塞
        if q.qsize() < 10:
            q.put('商品%s' % count)
            count += 1


# 消费者
def consumers(name):
    # 每隔一秒拿出一个商品
    while q.qsize() > 0:
        print('[%s] bought the [%s]' % (name, q.get()), q.qsize())
        time.sleep(1)


# 启动两个消费者线程一个生产者线程
man1 = threading.Thread(target=consumers, args=('test1', ))
man2 = threading.Thread(target=consumers, args=('test2', ))
goods = threading.Thread(target=producer)
goods.start()
man1.start()
man2.start()

上面是一个非常简单的生产者消费者模型,可以看到商品个数一直为9个,其实一直是10个,因为生产者生产的非常快,而消费者每一秒才买一个商品,然后生产者会立即填充,当然这种关系可以自己来调节

转载请注明出处

python自学技术互助扣扣群:670402334

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,246评论 11 349
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,130评论 25 707
  • 在对孩子的教育误区中,功利心是主要的诱因。有人会犯错误,就是因为——虽然大部分是无意识的——功利心。 ...
    夏小秋的后花园阅读 827评论 0 0
  • 姓名:赵丽萍 公司:宁波大发化纤有限公司 组别:第264期努力二组 【日精进打卡第94天】 【知~学习】 《六项精...
    zhaoliping阅读 89评论 0 0
  • 正紧张地看着《蟠虺》中因曾候乙尊盘而引发的盗墓贼与青铜器研究者所发生的惊险交锋,突然接到高伯伯打来的电话,先是格外...
    采葭小妖阅读 388评论 6 7