Queue - 一种线程安全的FIFO实现

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 def __lt__(self, other):
return 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')

Basic FIFO Queue的更多相关文章

  1. Python中Queue模块及多线程使用

    Python的Queue模块提供一种适用于多线程编程的FIFO实现.它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个 ...

  2. the Linux Kernel: Traffic Control, Shaping and QoS

    −Table of Contents Journey to the Center of the Linux Kernel: Traffic Control, Shaping and QoS 1 Int ...

  3. C++ std::queue

    std::queue template <class T, class Container = deque<T> > class queue; FIFO queue queue ...

  4. rabbitmq method之basic.consume

    basic.consume指的是channel在 某个队列上注册消费者,那在这个队列有消息来了之后,就会把消息转发到给此channel处理,如果 这个队列有多个消费者,则会采用轮转的方式将消息分发给消 ...

  5. 容器适配器之queue

    转载http://blog.csdn.net/thefutureisour/article/details/7751846容器适配器容器适配器其实就是一个接口转换装置,使得我们能用特定的方法去操作一些 ...

  6. STL中的单向队列queue

    转载自:http://blog.csdn.net/morewindows/article/details/6950917 stl中的queue指单向队列,使用时,包含头文件<queue>. ...

  7. Java学习笔记——浅谈数据结构与Java集合框架(第二篇、Queue、Set)

    江南好,何处异京华. 香散翠帘多在水,绿残红叶胜于花.无事避风沙. --<纳兰词> 诗词再好,大图不能忘 上大图: 先说说栈和队列: 栈就好比手枪的弹匣,你往里面压入子弹,最先压入的子弹就 ...

  8. python Queue在两个地方

    其一: Source code: Lib/queue.py The queue module implements multi-producer, multi-consumer queues. It ...

  9. 容器适配器(stack、 queue 、priority_queue)源码浅析与使用示例

    一.容器适配器 stack queue priority_queue stack.queue.priority_queue 都不支持任一种迭代器,它们都是容器适配器类型,stack是用vector/d ...

随机推荐

  1. 基于python机器学习人脸自动补全

    import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression ...

  2. springboot--springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  3. [APIO2009]会议中心

    [APIO2009]会议中心 题目大意: 原网址与样例戳我! 给定n个区间,询问以下问题: 1.最多能够选择多少个不相交的区间? 2.在第一问的基础上,输出字典序最小的方案. 数据范围:\(n \le ...

  4. 【BZOJ4530】大融合(Link-Cut Tree)

    [BZOJ4530]大融合(Link-Cut Tree) 题面 讨厌权限题!!! Loj链接 题目描述 小强要在 N个孤立的星球上建立起一套通信系统.这套通信系统就是连接 N个点的一个树.这个树的边是 ...

  5. C++学习-9

    友元主要用于访问私有变量,友元函数跟所在位置的权限没有任何关系friend+函数声明 友元类通常设计为一种对数据操作或类之间传递消息的辅助类(注意一下顺序) Explicit就是要求严格的匹配,不允许 ...

  6. 平衡树(Splay)模板

    支持区间操作. 单点操作和区间操作分开使用,需要一起使用需要部分修改. 对应题目FJUTOJ2490 #include<cstdio> #include<cstring> #i ...

  7. unity3D加密如何做到防编译?

    先介绍对unity3D程序进行加密的几种方式. Unity3D是一个基于Mono框架的跨平台游戏开发引擎,Unity3D所使用的Mono属于Mono开源项目的分支 在Unity3D中,代码会编译到As ...

  8. linux下Tomcat 安装后执行startup.sh,出现– Cannot find …bin/catalina.sh

    linux下Tomcat 安装后执行startup.sh,出现– Cannot find …bin/catalina.sh 是因为权限不够,执行以下命令就可以: chmod +x startup.sh ...

  9. 深入理解Java虚拟机(第2版) 笔记目录

    本篇为读深入理解Java虚拟机(第2版)一书的笔记目录. Java 运行期数据区 Java 垃圾回收算法 Java 内存分配策略 Java 类文件结构 Java 加载.链接.初始化 Java 类加载器

  10. 【转载】Perl中的引用

    为什么使用引用? 在perl4中,hash表中的value字段只能是scalar,而不能是list,这对于有些情况是很不方便的,比如有下面的数据: Chicago, USAFrankfurt, Ger ...