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

有了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 randint
from queue import Queue
from time import sleep
from test_8_25.mythread import MyThread


def 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 2017
Producing object for queue... None
Size now 1
Starting reader at: Sat Aug 26 19:27:42 2017
Consumed object from queue...
Size now 0
Producing object for queue... None
Size now 1
Producing object for queue... None
Size now 2
Consumed object from queue...
Size now 1
Consumed object from queue...
Size now 0
Producing object for queue... None
Size now 1
Consumed object from queue...
Size now 0
writer finished at: Sat Aug 26 19:27:53 2017
reader finished at: Sat Aug 26 19:27:53 2017
All done.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值