Queue - 一种线程安全的FIFO实现
<p>Queue - 一种线程安全的FIFO实现</p>
Python的Queue模块提供一种适用于多线程编程的FIFO实现。它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个线程可以共用同一个Queue实例。Queue的大小(元素的个数)可用来限制内存的使用。
Basic FIFO Queue
Queue
类实现了一个基本的先进先出(FIFO)
容器,使用put()
将元素添加到序列尾端,get()
从队列尾部移除元素。
from queue import Queue
q = Queue()
for i in range(3):
q.put(i)
while not q.empty():
print(q.get())
上例使用单线程演示了元素以插入顺序从队列中移除。结果如下:
0
1
2
3
LIFO Queue
与标准FIFO实现Queue
不同的是,LifoQueue
使用后进先出序(会关联一个栈数据结构)。
from queue import LifoQueue
q = LifoQueue()
for i in range(3):
q.put(i)
while not q.empty():
print(q.get())
最后put()
到队列的元素最先被get()
。
2
1
0
Priority Queue(优先队列)
除了按元素入列顺序外,有时需要根据队列中元素的特性来决定元素的处理顺序。例如,财务部门的打印任务可能比码农的代码打印任务优先级更高。PriorityQueue
依据队列中内容的排序顺序(sort order)来决定那个元素将被检索。
from queue import PriorityQueue
class Job(object):
def init(self, priority, description):
self.priority = priority
self.description = description
print(‘New job:’, description)
return
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__lt__</span><span class="hljs-params">(self, other)</span>:</span><span class="hljs-keyword">return</span> self.priority < other.priority
q = PriorityQueue()
q.put(Job(5, ‘Mid-level job’))
q.put(Job(10, ‘Low-level job’))
q.put(Job(1, ‘Important job’))
while not q.empty():
next_job = q.get()
print(‘Processing job’, next_job.description)
在这个单线程示例中,job会严格按照优先级从队列中取出。如有有多个线程同时消耗这些job,在get()
被调用时,job会依据其优先级被处理。
New job: Mid-level job
New job: Low-level job
New job: Important job
Processing job: Important job
Processing job: Mid-level job
Processing job: Low-level job
Using Queues with Threads
下例通过创建一个简单的播客客户端来展示如何将Queue类和多线程结合使用。这个客户端会从一个或多个RSS源读取内容,先创建一个用于存放下载内容的队列,然后使用多线程并行地处理多个下载任务。
import time
from queue import Queue
from threading import Thread
#: 自己写的解析模块
import feedparser
num_fetch_threads = 2
enclosure_queue = Queue()
feed_urls = [‘http:xxx/xxx’,]
def downloadEnclosures(i, q):
“”" 线程worker函数
用于处理队列中的元素项,这些守护线程在一个无限循环中,只有当主线程结束时才会结束循环
“”"
while True:
print(’%s: Looking for the next enclosure’ % i)
url = q.get()
print(’%s: Downloading: %s’ % (i, url))
#: 用sleep代替真实的下载
time.sleep(i + 2)
q.task_done()
for i in range(num_fetch_threads):
worker = Thread(target=downloadEnclosures, args=(i, enclosure_queue))
worker.setDaemon(True)
worker.start()
for url in feed_urls:
response = feedparser.parse(url, agent=‘fetch_podcasts.py’)
for entry in response[‘entries’]:
for enclosure in entry.get(‘enclosures’, []):
print(‘Queuing:’, enclosure[‘url’])
enclosure_queue.put(enclosure[‘url’])
# Now wait for the queue to be empty, indicating that we have
# processed all of the downloads.
print(’*** Main thread waiting’)
enclosure_queue.join()
print(’*** Done’)
</section>
Queue - 一种线程安全的FIFO实现相关推荐
- java中四种线程池及poolSize、corePoolSize、maximumPoolSize
目录 ThreadPoolExecutor重要参数 poolSize.corePoolSize.maximumPoolSize 四种线程池 newFixedThreadPool newCachedTh ...
- python 队列实现_Python Queue队列实现线程通信
queue 模块下提供了几个阻塞队列,这些队列主要用于实现线程通信.在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列.出队列的不同. 关于这三个队列类的简单介绍如下 ...
- python 优先队列_Python Queue队列实现线程通信
queue 模块下提供了几个阻塞队列,这些队列主要用于实现线程通信.在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列.出队列的不同.关于这三个队列类的简单介绍如下: ...
- java线程池详解及五种线程池方法详解
基础知识 Executors创建线程池 Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThrea ...
- Java ExecutorService四种线程池的例子与说明
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() {@Overridepublic void run() {// ...
- java常用的几种线程池
1. 为什么使用线程池 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协 ...
- Executors创建的4种线程池的使用
Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFi ...
- Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor...
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() {@Override public void run ...
- Java通过Executors提供四种线程池
http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如 ...
最新文章
- ESP32启明云端又有新玩法|基于ESP32+热像仪传感的物联网非接触智能测温终端为高考护航了
- java 数组遍历_Java中遍历数组使用foreach循环还是for循环?
- ServiceStack.Redis之IRedisClient第三篇
- JSP include指令和include动作的区别
- 数字测图原理与方法的实习日志_数字测图原理与方法实习与习题.doc
- 2018-06-12 python读二进制文件
- (6)机器学习_支持向量机
- 楚留香服务器维护时间,2019年06月28日官方维护公告
- iOS开发初学者需要经常去的论坛或网站
- GD32F303修改外部25M晶振
- 计算机应用技术在医院的应用,计算机应用技术对医院信息化的影响探讨
- 计算机研究计划怎么写,课题研究计划书范文
- 易支付PHP源码挖鱼网,最新易支付源码完整版 已pj全解密
- 2019 谷歌dat.GUI组件对中文的支持
- 第4套人民币收藏潜力显现 50元券半年涨近2倍
- 加推科技领读:2019,深圳开荒牛的TO B拓荒路
- 英语每日一句: What’s your point? 你到底想说什么?
- MU-MIMO技术让网络变神速的方法
- hadoop jar xxxx.jar 执行的流程
- signature=f4cc4caf9dfae5cdabe9df2bfa43b008,Derivatives of isoflavones
热门文章
- 如果在2008年用10万元投资腾讯,现在可以实现财务自由吗?
- DEVC++编译奇怪报错问题解决
- sql编程接收一个集合_T-SQL是基于集合的编程方法的资产
- ssis sql_SSIS OLE DB来源:SQL命令与表或视图
- sql limit 子句_具有并行性SQL Server TOP子句性能问题
- hive数据的导入导出方式
- 编写函数实现随机产生指定范围的整数的功能
- web项目使用配置web.xml实现重定向
- 搭建持续集成接口测试平台(Jenkins+Ant+Jmeter)
- java error:编码gbk的不可映射字符