当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。此模块中的Queue类实现了所有必需的锁定原语。 如果数据共享时可能被修改,就需要加锁来保护它,以确保同一时刻只能有一个线程访问这个数据。线程模块提供了许多同步原语,包括锁(Lock)、信号量(Semaphore)、条件变量(Condition)和事件(Event)。但最好的做法是使用Queue模块。Queue是线程安全的,使用它可以降低程序的复杂度,代码清晰,可读性更强。
# queue定义了三种类型的队列,maxsize为队列元素最大值,默认为无限大
# 定义一个先进先出的队列
class queue.Queue(maxsize=0)
# 定义一个后进先出的队列
class queue.LifoQueue(maxsize=0)
# 定义一个优先级队列,元素通常为(priority_number,data),值越小优先级越高
class queue.PriorityQueue(maxsize=0)
队列对象方法
Queue.qsize()
qsize()> 0不保证后续的get()不会阻塞,qsize()<maxsize也不保证put()不会阻塞??
Queue.empty()
如果队列为空,返回True,否则返回False。
Queue.full()
如果队列已满,返回True,否则返回False,如果返回True不保证get()不会阻塞,如果返回False也不保证put()不会阻塞。
Queue.put(item, block=True, timeout=None)
将元素插入到队列中。如果block=True和timeout等于None,将会发生阻塞直到有空闲的空间。如果timeout大于0,将会阻塞timeout秒,如果还是没有多余空间将会触发Full异常。如果block=False,如果队列不是满的直接放入队列,否则触发Full异常(timeout会被忽略)
Queue.put_nowait(item)
等于put(item, False).
Queue.get(block=True, timeout=None)
移除和返回队列中的元素。如果block=True和timeout等于None,将会发生阻塞直到队列不为空。如果timeout大于0,将会阻塞timeout秒,如果队列还是为空将会触发Empty异常。如果block=False,如果队列不为空返回元素,否则触发Empty异常(timeout会被忽略)
Queue.get_nowait()
等于get(False)
Queue.task_done()
表时以前排队的任务已经完成。用于队列消费者线程。对于用于获取任务的每个get(),对task_done()的后续调用会告知队列任务的处理已完成。
Queue.join()
阻塞直到队列中所有元素都被处理了。
import Queue
import threading
def print_url(queue):
while True:
url = queue.get()
print(url)
queue.task_done()
def use_queue():
queue = Queue.Queue()
for i in range(5):
t = threading.Thread(target=print_url,args=(queue,))
t.setDaemon(True)
t.start()
for url in ['baidu.com','xina.com','weibo.com','qq.com','hysky.com','hehe.com']:
queue.put(url)
queue.join()
if __name__ == "__main__":
use_queue()
# 输出:
baidu.com
weibo.com
xina.com
qq.com
hysky.com
hehe.com