Python 高级编程--多线程编程(四)

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()函数做的事比较类似,只是它是用来消耗对象的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值