详解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实现实例
Apr 26 Python
Python验证码识别的方法
Jul 10 Python
Python 文件处理注意事项总结
Apr 10 Python
python编程实现希尔排序
Apr 13 Python
pyqt5的QComboBox 使用模板的具体方法
Sep 06 Python
pymysql的简单封装代码实例
Jan 08 Python
使用Pycharm(Python工具)新建项目及创建Python文件的教程
Apr 26 Python
python Matplotlib数据可视化(2):详解三大容器对象与常用设置
Sep 30 Python
Python+logging输出到屏幕将log日志写入文件
Nov 11 Python
python之openpyxl模块的安装和基本用法(excel管理)
Feb 03 Python
matplotlib之pyplot模块之标题(title()和suptitle())
Feb 22 Python
Python识别花卉种类鉴定网络热门植物并自动整理分类
Apr 08 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
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
2012/03/07 PHP
php使用GD实现颜色渐变实例
2015/06/02 PHP
JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例
2013/06/29 Javascript
javascript获取下拉列表框当中的文本值示例代码
2013/07/31 Javascript
JavaScript的9种继承实现方式归纳
2015/05/18 Javascript
JS实现iframe编辑器光标位置插入内容的方法(兼容IE和Firefox)
2016/06/24 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
2016/10/10 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
nodejs学习笔记之路由
2017/03/27 NodeJs
vue-cli+webpack记事本项目创建
2017/04/01 Javascript
基于jQuery实现瀑布流页面
2017/04/11 jQuery
vue裁切预览组件功能的实现步骤
2018/05/04 Javascript
AngularJS 前台分页实现的示例代码
2018/06/07 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
JavaScript 实现轮播图特效的示例
2020/11/05 Javascript
Python闭包实现计数器的方法
2015/05/05 Python
python简单图片操作:打开\显示\保存图像方法介绍
2017/11/23 Python
python登录WeChat 实现自动回复实例详解
2019/05/28 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
python接口自动化之ConfigParser配置文件的使用详解
2020/08/03 Python
关于Python不换行输出和不换行输出end=““不显示的问题(亲测已解决)
2020/10/27 Python
最新版 Windows10上安装Python 3.8.5的步骤详解
2020/11/28 Python
使用pandas实现筛选出指定列值所对应的行
2020/12/13 Python
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
美国在线奢侈品寄售商店:Luxury Garage Sale
2018/08/19 全球购物
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
2012/05/24 面试题
医学专业毕业生个人的求职信
2013/12/04 职场文书
影视制作岗位职责
2013/12/04 职场文书
合作协议书范本
2014/10/25 职场文书
商务司机岗位职责
2015/04/10 职场文书
离职证明范本
2015/06/12 职场文书
同乡会致辞
2015/07/30 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书
mysql timestamp比较查询遇到的坑及解决
2021/11/27 MySQL