2.2.7.线程同步~Queue
1.基本使用
2.源码探讨
3.多任务调度
4.自定义Queue
补充
之前有人问 信号量在项目中有什么应用? ,这个其实从概念就推出场景了,控制并发嘛~举个例子:
比如说我们调用免费API的时候经常看见单位时间内限制并发数在30以内,想高并发==>给钱
再比如我们去爬数据的时候控制一下爬虫的并发数( ,其他部分后面会逐步引入)
这些虚的说完了,来个控制并发数的案例,然后咱们就继续并发编程的衍生了:
输出图示:
运行分析:
性能全图:
2.2.7.线程同步~Queue
1.基本使用
Queue在讲进程的时候就有说过(进程间通信),线程用法也差不多,看个经典案例:
输出图示:(非阻塞可以使用 和 )
2.源码探讨
Queue是线程安全的放心使用,我们来看看Queue源码:(条件变量 和 的综合使用)
3.多任务调度
来个场景,厂家倒闭(任务列表完成了)怎么通知消费者不用等待了?
回顾一下使用协程是怎么解决的:协程yield实现多任务调度
输出:
当使用 时,协调生产者和消费者的关闭问题可以在队列中放置一个特殊的值,当消费者读到这个值的时候,终止执行:
如果读到特殊值没有再放进队列就不能保证所有消费者都退出任务~Queue里面的数据取出来就没了输出:(你可以把上面那句注释调看结果)
在上面案例里面,你把 换成 ,然后比较部分的 换成 也是可以的,但是分布式系统的话还是使用 吧
4.自定义Queue
如果想在 的基础上扩展,可以自定义数据结构并添加所需的锁和同步机制(eg: )来实现线程间通信(同步)
写demo前说说理论:
二叉树 ==> 每个节点最多有两个子树的树结构
满二叉树 ==> 除了最底层叶结点外,每一个结点都有左右子叶
二叉堆 ==> 本质上是一种完全二叉树,它分为两个类型:
最大堆:最大堆任何一个父节点的值,都大于等于它左右子节点的值,根节点是最大值
最小堆:最小堆任何一个父节点的值,都小于等于它左右子节点的值,根节点是最小值
以最小堆为例,画个图演示一下:
插入新节点
排序后的二叉树
准备删除节点2
把最后一个节点拿过来充数(维护二叉树稳定)
进行比较排序,把左右节点最小的拉上来
构建二叉堆:把一个无序的完全二叉树调整为二叉堆( )
来个乱序的二叉树
从最后一个非叶子节点开始,和最小的子节点交换位置(8和1交换)
右边的也走一波(6和4交换)
节点5和1互换
现在根节点最小了(3和1互换)
从上往下再排个序,这时候就是最小堆了
看个 的规律:若从上至下、从左至右编号,则编号为i的结点:
左孩子编号为 ,其右孩子编号=
父节点编号= (根节点没有父节点)【Python 3/2=1.5,3//2=1】
把上面二叉树转换成数组:
这时候再去理解优先队列就简单了:
最大优先队列,无论入队顺序,当前最大的元素优先出队
最小优先队列,无论入队顺序,当前最小的元素优先出队
Python提供了一个 的模块:https://docs.python.org/3/library/heapq.html
来看个最小二叉堆的案例:
举个使用 + 实现一个优先级队列:
输出:
时候不早了,其他Queue类型下次再讲吧~
领取专属 10元无门槛券
私享最新 技术干货