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

Python的Queue模块提供一种适用于多线程编程的FIFO实现。它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个线程可以共用同一个Queue实例。Queue的大小(元素的个数)可用来限制内存的使用。

Basic FIFO Queue

Queue类实现了一个基本的先进先出(FIFO)容器,使用put()将元素添加到序列尾端,get()从队列尾部移除元素。

+
  1. from queue import Queue
  2. q = Queue()
  3. for i in range(3):
  4. q.put(i)
  5. while not q.empty():
  6. print(q.get())

上例使用单线程演示了元素以插入顺序从队列中移除。结果如下:

  1. 0
  2. 1
  3. 2
  4. 3

LIFO Queue

与标准FIFO实现Queue不同的是,LifoQueue使用后进先出序(会关联一个栈数据结构)。

  1. from queue import LifoQueue
  2. q = LifoQueue()
  3. for i in range(3):
  4. q.put(i)
  5. while not q.empty():
  6. print(q.get())

最后put()到队列的元素最先被get()

  1. 2
  2. 1
  3. 0

Priority Queue(优先队列)

除了按元素入列顺序外,有时需要根据队列中元素的特性来决定元素的处理顺序。例如,财务部门的打印任务可能比码农的代码打印任务优先级更高。PriorityQueue依据队列中内容的排序顺序(sort order)来决定那个元素将被检索。

  1. from queue import PriorityQueue
  2. class Job(object):
  3. def __init__(self, priority, description):
  4. self.priority = priority
  5. self.description = description
  6. print('New job:', description)
  7. return
  8. def __lt__(self, other):
  9. return self.priority < other.priority
  10. q = PriorityQueue()
  11. q.put(Job(5, 'Mid-level job'))
  12. q.put(Job(10, 'Low-level job'))
  13. q.put(Job(1, 'Important job'))
  14. while not q.empty():
  15. next_job = q.get()
  16. print('Processing job', next_job.description)

在这个单线程示例中,job会严格按照优先级从队列中取出。如有有多个线程同时消耗这些job,在get()被调用时,job会依据其优先级被处理。

  1. New job: Mid-level job
  2. New job: Low-level job
  3. New job: Important job
  4. Processing job: Important job
  5. Processing job: Mid-level job
  6. Processing job: Low-level job

Using Queues with Threads

下例通过创建一个简单的播客客户端来展示如何将Queue类和多线程结合使用。这个客户端会从一个或多个RSS源读取内容,先创建一个用于存放下载内容的队列,然后使用多线程并行地处理多个下载任务。

  1. import time
  2. from queue import Queue
  3. from threading import Thread
  4. #: 自己写的解析模块
  5. import feedparser
  6. num_fetch_threads = 2
  7. enclosure_queue = Queue()
  8. feed_urls = ['http:xxx/xxx',]
  9. def downloadEnclosures(i, q):
  10. """ 线程worker函数
  11. 用于处理队列中的元素项,这些守护线程在一个无限循环中,只有当主线程结束时才会结束循环
  12. """
  13. while True:
  14. print('%s: Looking for the next enclosure' % i)
  15. url = q.get()
  16. print('%s: Downloading: %s' % (i, url))
  17. #: 用sleep代替真实的下载
  18. time.sleep(i + 2)
  19. q.task_done()
  20. for i in range(num_fetch_threads):
  21. worker = Thread(target=downloadEnclosures, args=(i, enclosure_queue))
  22. worker.setDaemon(True)
  23. worker.start()
  24. for url in feed_urls:
  25. response = feedparser.parse(url, agent='fetch_podcasts.py')
  26. for entry in response['entries']:
  27. for enclosure in entry.get('enclosures', []):
  28. print('Queuing:', enclosure['url'])
  29. enclosure_queue.put(enclosure['url'])
  30. # Now wait for the queue to be empty, indicating that we have
  31. # processed all of the downloads.
  32. print('*** Main thread waiting')
  33. enclosure_queue.join()
  34. 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. Mac上使用虚拟机搭建Hadoop集群

    一. mini安装一台centos到虚拟机上 安装过程参考这篇博客http://www.linuxdown.net/install/setup/2015/0906/4053.html 二. 修改网络配 ...

  2. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  3. 【BZOJ2818】Gcd(莫比乌斯反演)

    [BZOJ2818]Gcd(莫比乌斯反演) 题面 Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的 数对(x,y)有多少对. Input 一个整数N Ou ...

  4. [luogu3600]随机数生成器

    题面在这里 题意 给定n个[1-x]的随机整数\(a_1,a_2,a_3,...,a_n\)和q个询问区间\((l_i,r_i)\), 求出\(\max_{i=1}^{q}({\min_{j=l_i} ...

  5. 【Luogu2759】奇怪的函数(数论)

    [Luogu2759]奇怪的函数(数论) 题面 题目描述 使得 \(x^{x}\)达到或超过 n 位数字的最小正整数 x 是多少? 输入输出格式 输入格式: 一个正整数 n 输出格式: 使得 \(x^ ...

  6. VS中Ctrl+F5(开始执行不调试)一闪而过问题

    昨天学弟学妹在使用VS2015时,遇到了Ctrl+F5运行完毕程序窗口不能停留的问题,感觉比较奇怪.后来了解到他们建立C++解决方案时,直接选中的是空项目,而这样就会导致这样的现象. 想要达到运行完毕 ...

  7. Hadoop集群环境安装

    转载请标明出处:  http://blog.csdn.net/zwto1/article/details/45647643:  本文出自:[zhang_way的博客专栏] 工具: 虚拟机virtual ...

  8. linux实验一 双系统安装

    (一)首先来简要了解一些linux的概念! 1.发行版本和内核版本的区别与联系:linux发行版本是"内核版本+一系列挂载软件"的集合体,光是一个内核版本是无法当做操作系统运行的. ...

  9. [sharepoint]rest api文档库文件上传,下载,拷贝,剪切,删除文件,创建文件夹,修改文件夹属性,删除文件夹,获取文档列表

    写在前面 最近对文档库的知识点进行了整理,也就有了这篇文章,当时查找这些接口,并用在实践中,确实废了一些功夫,也为了让更多的人走更少的弯路. 系列文章 sharepoint环境安装过程中几点需要注意的 ...

  10. Java反射总结

    一. 获取Class对象的3种方法: 1. Class.forName("");例如:Class.forName("java.lang.String"); 2. ...