队列家庭作业帮助
队列模块提供适用于多线程编程的FIFO实现。它可以用于安全地在生产者和消费者线程之间传递消息或其他数据。为调用者处理锁定,因此要使用同一个Queue实例具有尽可能多的线程很简单。队列的大小(元素数量)可能会被限制为限制内存使用或处理。
注意
这个讨论假设你已经了解了队列的一般性质。如果没有,您可能需要在继续之前阅读一些参考。
基本FIFO队列
Queue类实现了一个基本的先入先出的容器。使用put()将元素添加到序列的一个“end”,并从另一端使用get()进行删除。
导入队列
q = Queue.Queue()
对于我在范围(5):
q.put(i)
而不是q.empty():
打印q.get()
此示例使用单个线程来说明以与插入的顺序相同的顺序从队列中删除元素。
$ python Queue_fifo.py
LIFO队列
与Queue的标准FIFO实现相反,LifoQueue使用最后进先出顺序(通常与堆栈数据结构相关联)。
导入队列
q = Queue.LifoQueue()
对于我在范围(5):
q.put(i)
而不是q.empty():
打印q.get()
get()删除最近put()到队列中的项目。
$ python Queue_lifo.py
4
3
2
1
0
优先队列
有时,队列中项目的处理顺序需要基于这些项目的特征,而不仅仅是它们创建或添加到队列中的顺序。例如,来自工资部门的打印作业可能优先于开发人员打印的代码列表。 PriorityQueue使用队列内容的排序顺序决定要检索的内容。
导入队列
类Job(对象):
def __init __(self,priority,description):
self.priority =优先级
self.description = description
打印“新工作:”,说明
返回
def __cmp __(self,other):
返回cmp(self.priority,other.priority)
q = Queue.PriorityQueue()
q.put(Job(3,’中级职位’))
q.put(Job(10,’Low-level job’))
q.put(Job(1,’Important job)))
而不是q.empty():
next_job = q.get()
打印“处理作业:”,next_job.description
在这个单线程示例中,作业以严格的优先顺序从队列中拉出。如果有多个线程使用这些作业,则会根据调用get()时队列中的项目的优先级进行处理。
$ python Queue_priority.py
新工作:中级工作
新工作:低级工作
新工作:重要的工作
加工工作:重要工作
加工工作:中级工作
处理工作:低级工作
使用队列与线程
作为如何使用具有多个线程的Queue类的示例,我们可以创建一个非常简单的播客客户端。该客户端读取一个或多个RSS源,将机箱排队下载,并使用线程并行处理多个下载。它是简单的并且不适合实际使用,但骨架实现给我们足够的代码来提供使用队列模块的示例。
#系统模块
从队列导入队列
从线程导入线程
进口时间
#本地模块
导入feedparser
#设置一些全局变量
num_fetch_threads = 2
enclosure_queue = Queue()
#一个真正的应用程序不会使用硬编码的数据…
def downloadEnclosures(i,q):
“”“这是工作线程的功能。
它后来处理队列中的项目
另一个。这些守护进程线程进入
无限循环,只有退出
主线结束。
“”“
而真:
打印’%s:寻找下一个机箱’%i
url = q.get()
打印’%s:下载:’%i,url
#而不是真正下载URL,
#我们只是假装睡觉
time.sleep(i + 2)
q.task_done()
#设置一些线程来获取机箱
对于我的范围(num_fetch_threads):
worker = Thread(target = downloadEnclosures,args =(i,enclosure_queue,))
worker.setDaemon(True)
worker.start()
#下载Feed并放入机箱URL
#队列。
在feed_urls中的url:
response = feedparser.parse(url,agent =’fetch_podcasts.py’)
作为回应[‘条目’]:
对于entry.get(’enclosureures’,[])中的包围:
打印’Queuing:’,enclosure [‘url’]
enclosure_queue.put(enclosure [‘url’])
#现在等待队列为空,表示我们有
#处理了所有的下载。
打印’***主线程等待’
enclosure_queue.join()
打印’***完成’
首先,我们建立一些操作参数。通常这些来自用户输入(偏好,数据库,无论如何)。对于我们的例子,我们硬编码要使用的线程数和要获取的URL列表。
接下来,我们需要定义在工作线程中运行的函数downloadEnclosures(),处理下载。再次,为了说明的目的,这只是模拟下载。要实际下载机箱,您可以使用urllib或urllib2。在这个例子中,我们通过休眠一段时间来模拟一个下载延迟,这取决于线程ID。
一旦定义了线程的目标函数,我们可以启动工作线程。请注意,downloadEnclosures()将阻塞语句url = q.get(),直到队列有某些东西要返回,所以在队列中有任何东西之前启动线程是安全的。
下一步是检索Feed内容(使用Mark Pilgrim的feedparser模块)并排列机箱的URL。一旦将第一个URL添加到队列中,其中一个工作线程就应该将其加载并开始下载。下面的循环将继续添加项目,直到Feed耗尽,并且工作线程将轮流列出URL来下载它们。
而唯一要做的就是等待队列再次清空,使用join()。
队列模块实现多生产者,多消费者队列。当信息必须在多个线程之间安全交换时,它在线程编程中特别有用。该模块中的Queue类实现了所有必需的锁定语义。这取决于Python中线程支持的可用性;看到线程模块。
该模块实现三种类型的队列,它们仅在检索条目的顺序上有所不同。在FIFO队列中,添加的第一个任务是首次检索。在LIFO队列中,最近添加的条目是第一个检索的(像堆栈一样运行)。使用优先级队列,将条目保留排序(使用heapq模块),并且首先检索最低值条目。
Queue模块定义了以下类和异常:
Queue.Queue(maxsize = 0)
FIFO队列的构造方法maxsize是一个整数,用于设置可以放置在队列中的项目数量的上限。一旦达到此大小,插入将阻止,直到消耗队列项。如果maxsize小于或等于零,则队列大小为无穷大。
类Queue.LifoQueue(maxsize = 0)
LIFO队列的构造方法maxsize是一个整数,用于设置可以放置在队列中的项目数量的上限。一旦达到此大小,插入将阻止,直到消耗队列项。如果maxsize小于或等于零,则队列大小为无穷大。
新版本2.6。
类Queue.PriorityQueue(maxsize = 0)
优先级队列的构造方法maxsize是一个整数,用于设置可以放置在队列中的项目数量的上限。一旦达到此大小,插入将阻止,直到消耗队列项。如果maxsize小于或等于零,则队列大小为无穷大。
首先检索最低值条目(最低值条目是由sorted(list(entries))返回的值[0])。条目的典型模式是以下形式的元组:(priority_number,data)。
我们在homeworkchina为Python或Python Queues Homework提供专家帮助。我们的导师是为各级学生提供家庭作业帮助的专家。