python之Queue

当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。此模块中的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