Queue模块
Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,
和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。
Queue模块可以用来进行线程间通讯,让各个线程之间共享数据。
Queue模块常用的属性如下:
queue(size)
创建一个大小为size的Queue对象
qsize()
返回队列的大小(由于在返回的时候,队列可能会被其他线程修改,所以这个值是近似值)
empty()
如果队列为空返回True,否则返回False
full()
如果队列以满返回True,否则返回False
put( item[, block[, timeout]])
如果可选参数block为true并且timeout为None(缺省值),线程被block,直到队列空出一个数据单元。如果timeout大于0,
在timeout的时间内,仍然没有可用的数据单元,Full exception被抛出。反之,如果block参数为false(忽略timeout参数),
item被立即加入到空闲数据单元中,如果没有空闲数据单元,Full exception被抛出。put_nowait(item) 相当Queue.put(item, False)
get(block=0)
从队首取数据,其参数和put方法一样。如果block参数为true且timeout为None(缺省值),线程被block,直到队列中有数据。
如果timeout大于0,在timeout时间内,仍然没有可取数据,Empty exception被抛出。反之,如果block参数为false(忽略
timeout参数),队列中的数据被立即取出。如果此时没有可取数据,Empty exception也会被抛出。
get_nowait() 相当Queue.get(False)
task_done()
在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
join()
意味着等到队列为空,再执行别的操作
Queue解决生产者-消费者的问题,现在创建一个队列,让生产者线程把新生产的货物放进去供消费者线程使用。
生产者生产货物所要花费的时间无法预先确定,消费者消耗生产者生产的货物的时间也是不确定的。
from random import randint
from time import sleep
from Queue import Queue
from MyThread import MyThread
def writeQ(queue):
print '+++producting object for Q...',
queue.put('xxx',1)
print '+++size now:',queue.qsize()
def readQ(queue):
val=queue.get(1)
print '---consumed object from Q... size now',\
queue.qsize()
def writer(queue,loops):
for i in range(loops):
writeQ(queue)
sleep(randint(1,3))
def reader(queue,loops):
for i in range(loops):
readQ(queue)
sleep(randint(2,5))
funcs=[writer,reader]
nfuncs=range(len(funcs))
def main():
nloops=randint(3,5)
q=Queue(32)
threads=[]
for i in nfuncs:
t=MyThread(funcs[i],(q,nloops),\
funcs[i].__name__)
threads.append(t)
for i in nfuncs:
threads[i].start()
for i in nfuncs:
threads[i].join()
print "****** all done ******"
if __name__=='__main__':
main()
starting writer at: Wed Sep 13 15:05:10 2017
+++producting object for Q...starting reader+++size now: at: 1Wed Sep 13 15:05:10 2017
---consumed object from Q... size now 0
+++producting object for Q... +++size now: 1
---consumed object from Q... size now 0
+++producting object for Q... +++size now: 1
---consumed object from Q... size now 0
writer finish at: Wed Sep 13 15:05:16 2017
reader finish at: Wed Sep 13 15:05:20 2017
****** all done ******
这个实现中使用了Queue对象和随机地生产(和消耗)货物的方式。生产者和消费者相互独立并且并发地运行,它们
不一定是轮流执行的(随机数模拟)。writeQ()和readQ()函数分别用来把对象放入队列和消耗队列中的一个对象,
在这里使用字符串'xxx'来表示队列中的对象。writer()函数就是一次往队列中放入一个对象,等待一会然后再做同样
的事,一共做指定的次数,这个次数是由脚本运行时随机生成的。reader()函数做的事比较类似,只是它是用来消耗对象的。