Python 多线程|Queue队列|生产者消费者模式|

时间:2020-12-07 17:37:35

Queue队列

  • Python中,队列是线程间最常用的交换数据的形式。Queue模块是提供队列操作的模块,虽然简单易用,但是不小心的话,还是会出现一些意外。Queue是线程安全的,自带锁,使用的时候,不用对队列加锁操作。
1. 将一个值放入队列中

q.get()调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

2. Python Queue模块有三种队列及构造函数:
  • 1.Python Queue模块的FIFO队列先进先出。 class Queue.Queue(maxsize)
  • 2.LIFO类似于堆,即先进后出。 class Queue.LifoQueue(maxsize)
    1. 还有一种是优先级队列级别越低越先出来。 class Queue.PriorityQueue(maxsize)
3. 此包中的常用方法

(q.qsize() 返回队列的大小q.empty() 如果队列为空,返回True,反之Falseq.full() 如果队列满了,返回True,反之Falseq.full 与 maxsize 大小对应
q.get([block[, timeout]]) 获取队列,timeout等待时间
q.get_nowait() 相当q.get(False)非阻塞 q.put(item) 写入队列,timeout等待时间q.put_nowait(item) 相当q.put(item, False)
q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号q.join() 实际上意味着等到队列为空,再执行别的操作

4.代码实例

实现一个线程不断生成一个随机数到一个队列中(考虑使用Queue这个模块)
实现一个线程从上面的队列里面不断的取出奇数
实现另外一个线程从上面的队列里面不断取出偶数

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import Queue
import random
import time


class Producter(threading.Thread):
"""生产者线程"""
def __init__(self, t_name, queue):
self.queue = queue
threading.Thread.__init__(self, name=t_name)

def run(self):
for i in range(10):
randomnum = random.randint(1, 99)
self.queue.put(randomnum)
print 'put num in Queue %s' % randomnum
time.sleep(1)

print 'put queue done'


class ConsumeEven(threading.Thread):
"""奇数消费线程"""
def __init__(self, t_name, queue):
self.queue = queue
threading.Thread.__init__(self, name=t_name)

def run(self):
while True:
try:
queue_val = self.queue.get(1, 3)
except Exception, e:
print e
break;

if queue_val % 2 == 0:
print 'Get Even Num %s ' % queue_val
else:
self.queue.put(queue_val)


q = Queue.Queue()
pt = Producter('producter', q)
ce = ConsumeEven('consumeeven', q)
ce.start()
pt.start()
pt.join()
ce.join()