python 队列 锁_python3线程相关(2)—— 队列、GIL锁

线程队列Queue(先进先出队列)

我们继续包子铺的故事。包子铺生意非常好,经常有很多顾客需要排队,处于文明礼貌,当然就是先排队的顾客先买到包子。包子铺排队也经常会发生下面一些情形:1、包子铺店员喊”下一个“时,排在最前的顾客就可以掏钱买包子啦。如果没有顾客排队呢,有时候包子铺就直接收摊,有时候包子铺会等一段时间再收摊,有时候是一直不收摊就等顾客来。

2、正在买包子的顾客买完包子有时会回头对排队的顾客说:”我买好了,今天的包子不错“。

3、有时生意很火爆,新来的顾客过来,看到队伍已经排蛮整个街道呢,有些会直接走人,有些会等一会如果还没位置再走人,还有些则选择一直等知道有空位出来。

4、有时候老板搞推广活动,要求每个买包子的人买完包子后都对排队的顾客反馈一声”我买好了,今天的包子不错“,只有所有的顾客都给出了好反馈,才能宣布活动成功,每位顾客也能得到相应优惠。

在python编程中,线程队列就对应了现实中包子铺顾客排队的情形。

队列Queue有以下方法:Queue.qsize() : 返回队列大小

Queue.empty() : 判断队列是否为空

Queue.full() : 判断队列是否满了

Queue.get([block[,timeout]]): 对应包子铺排队情形1。从队列头取出一个item,block默认为True,表示当队列为空时候阻塞线程,等待queue中有item可以取(一直等顾客来)。如果是False的话表明当队列没有item可取时引发异常(没有顾客直接收工)。在block为True的情况下可以再设置timeout参数。表示当队列为空,阻塞timeout指定的秒数队列还空得话就引发Full异常(等顾客一段时间还没有就手工)。

Queue.task_done(): 对应包子铺排队情形2。处理完一个get出来的item之后,调用task_done将向队列发出一个信号(”我买好了,今天的包子不错“),表示本任务已经完成(与Queue.get配对使用)。

Queue.put(…[,block[,timeout]]): 对应包子铺排队情形3。向队尾插入一个item,若block=True的话队列满时就阻塞知道有空位出现(一直等排队),block=False时引发异常(看到队伍满就走人)。block=True情况下得timeout,,超时报异常(等一会再走)。

Queue.join(),对应包子铺排队情形4。监视所有item并阻塞主线程,直到所有item都调用了task_done之后主线程才继续向下执行。这么做的好处在于,假如一个线程开始处理最后一个任务,它从任务队列中拿走最后一个任务,此时任务队列就空了但最后那个线程还没处理完。当调用了join之后,主线程就不会因为队列空了而擅自结束,而是等待最后那个线程处理完成了(搞活动了)。join()可以理解为一个计数器,put了多少次,计数器就是多少,每task_done一次,计数器减1,当减到0时继续执行。

import threading

import queue

q = queue.Queue(5)

q.put(5)

print(q.get())

GIL锁(Global Interpreter Lock)

延续包子铺的故事。这家包子铺只有一块砧板,这就导致阿姨们只能轮流使用。为了有序,老板就规定,一位阿姨使用砧板1小时后就要让出,然后阿姨们谁抢到谁就用砧板。 另外,如果阿姨在使用砧板期间要把做好得包子拿去蒸,她也得让出砧板,而且短期内她没办法抢砧板,因为她要去厨房。

在python线程中,线程全局解释锁(GIL)就相当于包子铺得砧板,每执行100条字节码(对应使用砧板1小时),解释器就自动释放GIL,或者进行I/O时(对应去厨房蒸包子),也释放GIL。可以说,GIL保证同一时刻只有一个线程使用CPU执行代码,多线程不过时大家轮着上。

python互斥锁Lock与GIL锁的关系

首先假设只有一个进程,这个进程中有两个线程 Thread1,Thread2, 要修改共享的数据data, 并且有互斥锁,执行以下步骤:

GIL锁有python语言规定,是个被动得过程。 Thread1和Thread2必须在持有GIL锁得情况下才能执行代码。如Thread1持有GIL锁,Thread2会被阻塞。100条字节码后重新两线程重新抢GIL,或者Thread1进行I/O时,GIL锁由Thread2获得。

Lock锁是在线程执行时由线程中代码设置,是个主动得过程,用于锁定共享数据data,如果Thread2要使用数据data,就会被阻塞,直到Thread1对data进行解锁,并且Thread2在获取到GIL情况下才能对data进行修改。

Lock 和GIL避免了不同线程对共享数据同时进行操作,造成不可预料得错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值