Python多线程3:queue

queue模块实现了多生产者。多消费者队列。在多线程环境下,该队列能实现多个线程间安全的信息交换。

queue模块介绍

模块实现了3种类型的队列,差别在于队列中条目检索的顺序不同。

在FIFO队列中。依照先进先出的顺序检索条目。在LIFO队列中,最后加入的条目最先检索到(操作类似一个栈)。在优先级队列中,条目被保存为有序的(使用heapq模块)而且最小值的条目被最先检索。

queue模块定义了以下的类和异常:

class queue.Queue(maxsize=0)

FIFO队列的构造器。maxsize为一个整数。表示队列的最大条目数。一旦队列满,插入将被堵塞直到队列中存在空暇空间。假设maxsize小于等于0。队列大小为无限。

class queue.LifoQueue(maxsize=0)

LIFO队列的构造器。

maxsize是一个整数,表示队列的最大条目数。一旦队列满,插入将被堵塞直到队列中存在空暇空间。假设maxsize小于等于0,队列大小为无限。

class queue.PriorityQueue(maxsize=0)

优先级队列的构造器。maxsize是一个整数,表示队列的最大条目数。一旦队列满,插入将被堵塞直到队列中存在空暇空间。

假设maxsize小于等于0,队列大小为无限。

最小值的条目被最先检索到(最小值的条目即为被sorted(list(entries))[0]返回的条目)。

通常一个条目被保存为以下的形式:(priority_number, data)。

exception queue.Empty

当Queue为空时,非堵塞的get()或者get_nowait()被调用时,将抛出该异常。

exception queue.Full

当队列满时,非堵塞的put()或者put_nowait()被调用,将抛出该异常。

Queue对象

Queue对象(Queue、LifoQueue或者PriorityQueue)提供了下面方法:

Queue.qsize()

返回队列的近似大小。注意,qsize() > 0并不能保证接下来的get()方法不被堵塞。相同。qsize() < maxsize也不能保证put()将不被堵塞。

Queue.empty()

假设队列是空的。则返回True,否则False。假设empty()返回True,并不能保证接下来的put()调用将不被堵塞。类似的。empty()返回False也不能保证接下来的get()调用将不被堵塞。

Queue.full()

假设队列满则返回True,否则返回False。假设full()返回True,并不能保证接下来的get()调用将不被堵塞。

类似的,full()返回False也不能保证接下来的put()调用将不被堵塞。

Queue.put(item, block=True, timeout=None)

放item到队列中。假设block是True,且timeout是None。该方法将一直等待直到有队列有空余空间。假设timeout是一个正整数,该方法则最多堵塞timeout秒并抛出Full异常。假设block是False而且队列满,则直接抛出Full异常(这时timeout将被忽略)。

Queue.put_nowait(item)

等价于put(item, False)。

Queue.get(block=True, timeout=None)

从队列中移除被返回一个条目。假设block是True而且timeout是None,该方法将堵塞直到队列中有条目可用。假设timeout是正整数,该方法将最多堵塞timeout秒并抛出Empty异常。假设block是False而且队列为空。则直接抛出Empty异常(这时timeout将被忽略)。

Queue.get_nowait()

等价于get(False)。

假设须要跟踪进入队列中的任务是否已经被精灵消费者线程处理完毕,能够使用以下提供的两个方法:

Queue.task_done()

表示一个先前的队列中的任务完毕了。被队列消费者线程使用。对于每一个get()获取到的任务,接下来的task_done()的调用告诉队列该任务的处理已经完毕。

假设join()调用正在堵塞,当队列中全部的条目被处理后它将恢复运行(意味着task_done()调用将被放入队列中的每一个条目接收到)。

假设调用次数超过了队列中放置的条目数目,将抛出ValueError异常。

Queue.join()

堵塞直到队列中全部条目都被获取并处理。

当一个条目被添加到队列时,未完毕任务的计数将添加。当一个消费者线程调用task_done()时,未完毕任务的计数将降低。

当未完毕任务的计数降低到0时,join()解锁。

以下是一个详细的样例。用于说明怎么等待队列任务完毕:

def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()       # 堵塞直到全部任务完毕
时间: 2024-08-03 17:04:16

Python多线程3:queue的相关文章

python多线程编程-queue模块和生产者-消费者问题

摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue模块(python2.x版本中,叫Queue)来提供线程间通信的机制,从而让线程之间可以分享数据.具体而言,就是创建一个队列,让生产者(线程)在其中放入新的商品,而消费者(线程)消费这些商品. 下表是queue模块的部分属性: 属性 描述 queue模块的类 Queue(maxsize=0) 创建一

python多线程、多进程以及GIL

多线程 使用threading模块创建线程 传入一个函数 这种方式是最基本的,即调用threading中的Thread类的构造函数,然后指定参数target=func,再使用返回的Thread的实例调用start()方法,即开始运行该线程,该线程将执行函数func,当然,如果func需要参数,可以在Thread的构造函数中传入参数args=(-).示例代码如下 import threading #用于线程执行的函数 def counter(n): cnt = 0; for i in xrange

Python多线程学习资料1

一.Python中的线程使用: Python中使用线程有两种方式:函数或者用类来包装线程对象. 1.  函数式:调用thread模块中的start_new_thread()函数来产生新线程.如下例: view plaincopy to clipboardprint? import time import thread def timer(no, interval): cnt = 0 while cnt<10: print 'Thread:(%d) Time:%s\n'%(no, time.cti

Python多线程(threading)学习总结

注:此文除了例子和使用心得是自己写的,很多都是Python核心编程中的原文.原文文风应该能看出来,就不每个地方单独表明出处了. 线程(有时被称为轻量级进程)跟进程有些相似,不同的是,所有的线程运行在同一个进程中,共享相同的运行环境.它们可以想像成是在主进程或"主线程"中并行运行的"迷你进程". 线程有开始,顺序执行和结束三部分.它有一个自己的指令指针,记录自己运行到什么地方.线程的运行可能被抢占(中断),或暂时的被挂起(也叫睡眠),让其它的线程运行,这叫做让步.一个

python 多线程探索

前面已经了解过了,python多线程效率较低的主要原因是存在GIL,即Global Interpreter Lock(全局解释器锁).这里继续详细的看下GIL的说明与如何避免GIL的影响,从而提高python多线程的执行效率.什么是GIL首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.有名的编译器例如GCC,INTEL C++,Visual C++等

python多线程读取同一个文件

多线程读取同一个文件,要求不能重复,不能遗漏. 最开始尝试了一种方法(后来实践证明是无效的) 主线程分配给每个读线程需要读取文件中哪些行, 比如线程1读取1-10行,线程2读取11-30行. 然后每个线程通过readline()来读取,读到的行如果不属于本线程的范围,则continue跳过. 实践证明,这若干个线程并没有按照我们期望来读. 我的猜想是,通过open来打开一个文件,多个线程返回的是同一个句柄, 或者一个文件的文件指针只有一个. 经过网上搜索和实践,总结出有以下方法支持多线程读取同一

Python多线程目录扫描器

Python多线程目录扫描器,代码很简单,不过也花了我很多时间. 遇到文件如下: 多线程执行问题 队列执行问题 编码问题 目录问题 自己逻辑问题 报告长官,总结完毕,以下是成果,请长官查收: # coding:utf-8 import requests import threading import Queue import sys url_list = Queue.Queue() mutex = threading.Lock() def path(url): with open("./path

Python 多线程教程:并发与并行

Python 多线程教程:并发与并行 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程程序同时运行.因此,如果你是从其他语言(比如C++或Java)转过来的话,Python线程模块并不会像你想象的那样去运行.必须要说明的是,我们还是可以用Python写出能并发或并行的代码,并且能带来性能的显著提升,只要你能顾及到一些事情.如果你还没看过的话,我建议你看看

Python多线程学习

一.Python中的线程使用:     Python中使用线程有两种方式:函数或者用类来包装线程对象. 1.  函数式:调用thread模块中的start_new_thread()函数来产生新线程.如下例: import time import thread def timer(no, interval): cnt = 0 while cnt<10: print 'Thread:(%d) Time:%s\n'%(no, time.ctime()) time.sleep(interval) cnt

Python 多线程 -thread threading Queue- 简单学习

在实际工作过程中,会出现需要并发的做一些事情,例如一台机器测到几千台机器的网络连通性,如果你单线程一台一台测的话,会花费很多的事情,不具有实时性,更不能在变化的时候立刻感知当时网络的状况,这时多线程就是一个很好地选择.python已经给我们封装好了多线程库thread和threading. thread:比较底层的模块 threading:Higher-level threading interface ps:建议使用threading模块 - 高级别的threading模块更为先进,对线程的支