Python多线程--(4)queue对象

来源:互联网 发布:博客下载软件 编辑:程序博客网 时间:2024/05/22 15:32

有了Python线程的基础概念Python多线程–(1)之基本概念
在python中应用线程,threading模块的了解Python多线程–(2)之threading模块
以及多线程编程中最重要的一方面–同步 Python多线程–(3)同步


在上一篇同步举的例子中,我们模拟了向资源池中填入和消耗资源这个过程,填入和消耗的时间都是不确定的,其实我们用信号量已经实现了线程间的通信–在表示共享资源的数量上。不过python还给我们提供了queue模块(Python 2.x版本中为Queue),它提供了线程间的通信机制,可以让线程之间可以分享数据。

具体来说,实现的方式也是和很简单的,可以理解为创建了一个公共可以访问的队列,线程都可以访问它。具体的queue模块有的一些属性如下:

queue模块中的类:

  • Queue(maxsize=0):创建一个先入先出的队列,最大值可以限制队列的空间,如果没有限定则为无限值。
  • LifoQueue(maxsize=0):创建一个先入后出的队列,也就是类似栈的东西。最大值可以限制队列的空间,如果没有限定则为无限值。
  • PriorQueue(maxsize=0):创建一个优先级的队列,最大值可以限制队列的空间,如果没有限定则为无限值。

异常:

  • Empty():对列为空的时候调用get*()方法抛出异常
  • Full():队列满时调用put*()方法抛出异常

queue对象方法:

  • qsize():返回队列大小,不过其他线程可能改变队列大小,这个值不准确。
  • empty():判断队列是为空,布尔值空为True,否则Flase。
  • full():判断队列是否满,布尔值满为True,否则为Flase。
  • put(item, block=True, timeout=None):把item放入队列中,block=True,timeout=None,则会等待直到有可用空间,timeout有值则最多阻塞多少秒。block=Flase就会抛出Empty异常。
  • put_nowait(item)同put(item,Flase)。
  • get(block=True,timeout=None):从队列中取得元素,block=True则阻塞到有可用元素
  • get_nowait():同get(Flase)。
  • task_done():用于表示队列中某个元素执行完成,和下一个方法join()一起配合使用
  • join():在队列中所有元素执行完前并调用上一个task_done()之前保持阻塞。

之前的信号量例子,改用queue来进行资源的共享

from random import randintfrom queue import Queuefrom time import sleepfrom test_8_25.mythread import MyThreaddef write_queue(queue):    # 添加队列中元素行为    print('Producing object for queue...', queue.put('xxx', 1))    print('Size now', queue.qsize())def read_queue(queue):    #消耗队列中元素行为    queue.get(1)    print('Consumed object from queue...')    print('Size now', queue.qsize())def writer(queue, loops):    #随机向队列中添加随机个数的元素    for i in range(loops):        write_queue(queue)        sleep(randint(1, 3))def reader(queue, loops):    # 随机消耗队列中随机个数的元素    for i in range(loops):        read_queue(queue)        sleep(randint(2,5))#等待时间比writer常,尽量避免队列在消耗时为空funcs = [writer, reader]nfuncs = range(len(funcs))def main():    nloops =randint(2,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() #这里需要将线程挂起,否则主线程会线程结束前打印“all done”        # 或者你也可以使用atexit()来限制在主线程退出时在打印    print("All done.")if __name__ == '__main__':    main()

结果实例(结果随机不尽相同):

Starting writer at: Sat Aug 26 19:27:42 2017Producing object for queue... NoneSize now 1Starting reader at: Sat Aug 26 19:27:42 2017Consumed object from queue...Size now 0Producing object for queue... NoneSize now 1Producing object for queue... NoneSize now 2Consumed object from queue...Size now 1Consumed object from queue...Size now 0Producing object for queue... NoneSize now 1Consumed object from queue...Size now 0writer finished at: Sat Aug 26 19:27:53 2017reader finished at: Sat Aug 26 19:27:53 2017All done.
原创粉丝点击