详解Python中的四种队列


Posted in Python onMay 21, 2018

队列是一种只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

在Python文档中搜索队列(queue)会发现,Python标准库中包含了四种队列,分别是queue.Queue / asyncio.Queue / multiprocessing.Queue / collections.deque。

collections.deque

deque是双端队列(double-ended queue)的缩写,由于两端都能编辑,deque既可以用来实现栈(stack)也可以用来实现队列(queue)。

deque支持丰富的操作方法,主要方法如图:

详解Python中的四种队列 

相比于list实现的队列,deque实现拥有更低的时间和空间复杂度。list实现在出队(pop)和插入(insert)时的空间复杂度大约为O(n),deque在出队(pop)和入队(append)时的时间复杂度是O(1)。

deque也支持in操作符,可以使用如下写法:

q = collections.deque([1, 2, 3, 4])
print(5 in q) # False
print(1 in q) # True

deque还封装了顺逆时针的旋转的方法:rotate。

# 顺时针
q = collections.deque([1, 2, 3, 4])
q.rotate(1)
print(q) # [4, 1, 2, 3]
q.rotate(1)
print(q) # [3, 4, 1, 2]
# 逆时针
q = collections.deque([1, 2, 3, 4])
q.rotate(-1)
print(q) # [2, 3, 4, 1]
q.rotate(-1)
print(q) # [3, 4, 1, 2]

线程安全方面,collections.deque中的append()、pop()等方法都是原子操作,所以是GIL保护下的线程安全方法。

static PyObject *
deque_append(dequeobject *deque, PyObject *item) { 
 Py_INCREF(item);
 if (deque_append_internal(deque, item, deque->maxlen) < 0) 
 return NULL;
 Py_RETURN_NONE;
}

通过dis方法可以看到,append是原子操作(一行字节码)。

详解Python中的四种队列 

综上,collections.deque是一个可以方便实现队列的数据结构,具有线程安全的特性,并且有很高的性能。

queue.Queue & asyncio.Queue

queue.Queue和asyncio.Queue都是支持多生产者、多消费者的队列,基于collections.deque,他们都提供了Queue(FIFO队列)、PriorityQueue(优先级队列)、LifoQueue(LIFO队列),接口方面也相同。

区别在于queue.Queue适用于多线程的场景,asyncio.Queue适用于协程场景下的通信,由于asyncio的加成,queue.Queue下的阻塞接口在asyncio.Queue中则是以返回协程对象的方式执行,具体差异如下表:

详解Python中的四种队列

multiprocessing.Queue

multiprocessing提供了三种队列,分别是Queue、SimpleQueue、JoinableQueue。

详解Python中的四种队列 

multiprocessing.Queue既是线程安全也是进程安全的,相当于queue.Queue的多进程克隆版。和threading.Queue很像,multiprocessing.Queue支持put和get操作,底层结构是multiprocessing.Pipe。

multiprocessing.Queue底层是基于Pipe构建的,但是数据传递时并不是直接写入Pipe,而是写入进程本地buffer,通过一个feeder线程写入底层Pipe,这样做是为了实现超时控制和非阻塞put/get,所以Queue提供了join_thread、cancel_join_thread、close函数来控制feeder的行为,close函数用来关闭feeder线程、join_thread用来join feeder线程,cancel_join_thread用来在控制在进程退出时,不自动join feeder线程,使用cancel_join_thread有可能导致部分数据没有被feeder写入Pipe而导致的数据丢失。

和threading.Queue不同的是,multiprocessing.Queue默认不支持join()和task_done操作,这两个支持需要使用mp.JoinableQueue对象。

SimpleQueue是一个简化的队列,去掉了Queue中的buffer,没有了使用Queue可能出现的问题,但是put和get方法都是阻塞的并且没有超时控制。

总结

通过对比可以发现,上述四种结构都实现了队列,但是用处却各有偏重,collections.deque在数据结构层面实现了队列,但是并没有应用场景方面的支持,可以看做是一个基础的数据结构。queue模块实现了面向多生产线程、多消费线程的队列,asyncio.queue模块则实现了面向多生产协程、多消费协程的队列,而multiprocessing.queue模块实现了面向多成产进程、多消费进程的队列。

以上所述是小编给大家介绍的Python中的四种队列,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python 文件管理实例详解
Nov 10 Python
Python中的条件判断语句基础学习教程
Feb 07 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
Jul 04 Python
Python OpenCV调用摄像头检测人脸并截图
Aug 20 Python
python 图像处理画一个正弦函数代码实例
Sep 10 Python
python列表插入append(), extend(), insert()用法详解
Sep 14 Python
解析PyCharm Python运行权限问题
Jan 08 Python
python发qq消息轰炸虐狗好友思路详解(完整代码)
Feb 15 Python
如何使用repr调试python程序
Feb 28 Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
Jun 03 Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 Python
python基于tkinter制作无损音乐下载工具
Mar 29 Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
May 21 #Python
Python自定义函数实现求两个数最大公约数、最小公倍数示例
May 21 #Python
Python基于递归和非递归算法求两个数最大公约数、最小公倍数示例
May 21 #Python
Python常用字符串替换函数strip、replace及sub用法示例
May 21 #Python
Python下使用Scrapy爬取网页内容的实例
May 21 #Python
python 每天如何定时启动爬虫任务(实现方法分享)
May 21 #Python
对python抓取需要登录网站数据的方法详解
May 21 #Python
You might like
Windows IIS PHP 5.2 安装与配置方法
2009/06/08 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
php网页病毒清除类
2014/12/08 PHP
php通过array_merge()函数合并关联和非关联数组的方法
2015/03/18 PHP
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
2020/01/04 PHP
js 实现无干扰阴影效果 简单好用(附文件下载)
2009/12/27 Javascript
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
jquery maxlength使用说明
2011/09/09 Javascript
JavaScript人脸识别技术及脸部识别JavaScript类库Tracking.js
2015/09/14 Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
2016/01/18 Javascript
原生js实现中奖信息无间隙滚动效果
2017/01/18 Javascript
基于jQuery封装的分页组件
2017/06/26 jQuery
Vue实现Layui的集成方法步骤
2020/04/10 Javascript
VSCode搭建React Native环境
2020/05/07 Javascript
vue 实现一个简单的全局调用弹窗案例
2020/09/10 Javascript
[32:26]EG vs IG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[02:04]2020年夜魇暗潮预告片
2020/10/30 DOTA
[46:42]DOTA2-DPC中国联赛正赛 Aster vs Magma BO3 第二场 3月5日
2021/03/11 DOTA
Python使用PIL模块生成随机验证码
2017/11/21 Python
django rest framework 数据的查找、过滤、排序的示例
2018/06/25 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
利用python求积分的实例
2019/07/03 Python
python 批量添加的button 使用同一点击事件的方法
2019/07/17 Python
Selenium使用Chrome模拟手机浏览器方法解析
2020/04/10 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
Maje德国官网:法国女性成衣品牌
2017/02/10 全球购物
荷兰电脑专场:Paradigit
2018/05/05 全球购物
英国外籍人士的在线超市:British Corner Shop
2019/06/03 全球购物
《青海高原一株柳》教学反思
2014/04/25 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
2015年机关后勤工作总结
2015/05/26 职场文书
Python爬取科目四考试题库的方法实现
2021/03/30 Python
vue的项目如何打包上线
2022/04/13 Vue.js