zoukankan      html  css  js  c++  java
  • Python3之并发(七)---线程同步队列(queue)

    queue模块实现了多生产者,多消费者队列

    queue模块的常用类和异常

    queue.Queue(maxsize=0)
    先进先出(FIFO)的队列,
    maxsize: 队列的大小(即队列的元素个数),默认0,队列大小无限;如果超过maxsize,队列会加锁,添加新元素是被堵塞,直到队列中的元素小于maxsize
    
    queue.LifoQueue(maxsize=0)
    后进先出(LIFO)的队列
    maxsize参数同 queue.Queue 用法一样
    
    queue.PriorityQueue(maxsize=0)
    优先级队列,优先级小的元素先出,优先级通过 sorted(list(entries))[0] 的返回值决定
    maxsize参数同 queue.Queue 用法一样
    
    queue.SimpleQueue
    无限FIFO队列
    
    queue.Empty
    异常
    为空的queue对象调用 Queue.get() 方法引发该异常
    
    queue.Full
    异常
    已满的queue对象调用 Queue.put() 方法引发该异常

    队列对象方法

    Queue,LifoQueue,PriorityQueue对象的方法一样,使用Queue类说明

    Queue.qsize()
    返回队列的元素个数
    
    Queue.empty()
    队列为空返回 True,否则返回 False
    
    Queue.full()
    队列已满返回 True,否则返回 False
    
    Queue.put(item, block=True, timeout=None)
    往队列里加入item,即生产元素,默认队列已满时会堵塞不引发异常
    block: 队列已满时是否堵塞当前准备往队列里加入元素的线程,默认True
    timeout: 线程被堵塞的时长,默认None
    若队列已满且block=False,会引发 queue.FULL 异常
    若队列已满且block=True,在timeout时间内,队列一直处于已满状态,引发 queue.FULL 异常
    
    Queue.put_nowait(item)
    相当于Queue.put(item, block=False),队列元素已满,直接引发queue.FULL异常
    
    Queue.get(block=True, timeout=None)
    删除并返回队列里的一个item,即消费元素,默认队列已空时会堵塞不引发异常
    block: 队列已空时是否堵塞当前准备往队列里取出元素的线程,默认True
    timeout: 线程被堵塞的时长,默认None,
    若队列已空且block=False,会引发 queue.Empty 异常
    若队列已空且block=True,在timeout时间内,队列一直处于空状态,引发 queue.Empty异常
    
    Queue.get_nowait()
    相当于Queue.get(block=False),队列元素为空,直接引发 queue.Empty 异常
    
    
    Queue.task_done()
    使用 Queue.get() 方法之后,调用该方法告诉队列当前任务已完成,队列里的item减少一个
    通常配合 Queue.join() 方法使用
    
    Queue.join()
    堵塞当前线程,知道对垒中的所有任务完成
    当队列的item数量为0,Queue.join() 方法取消堵塞

    示例

    import threading, queue
    from concurrent.futures import ThreadPoolExecutor
    
    #账户类
    class Account:
        def __init__(self, account_no, balance):
            #账户编号和账户余额
            self.account_no = account_no
            self.balance = balance
        
        def getBlance(self):
            return self.balance
        
        #提取现金方法
        def draw(self, queues):
                draw_amount = queues.get()
                if self.balance >= draw_amount:
                    print(threading.current_thread().name+'	取钱成功!吐出钞票:'+str(draw_amount))
                    self.balance -= draw_amount
                    print(threading.current_thread().name+'操作之后	余额为:'+str(self.balance))
                else:
                    print(threading.current_thread().name+'	取钱失败!余额不足!	当前余额为:'+str(self.balance))
                queues.task_done()
    
        #存钱方法
        def deposit(self, queues):
                deposit_amount = queues.get()
                print(threading.current_thread().name+'	存钱成功!存入钞票:'+str(deposit_amount))
                self.balance += deposit_amount
                print(threading.current_thread().name+'操作之后	余额为:'+str(self.balance))
                queues.task_done()
    
    queues = queue.Queue(10)
    
    for item in (2000, 1000, 1000, 900):
        queues.put(item)
    
    acct = Account('986623', 0)
    
    with ThreadPoolExecutor(10, thread_name_prefix='Account_Thread_Pool') as pools:
        pools.submit(acct.draw, queues)
        pools.submit(acct.deposit, queues)
        pools.submit(acct.deposit, queues)
        pools.submit(acct.draw, queues)
        queues.join()
    print(threading.current_thread().name+'结束')
    import queue, threading, time
    
    
    #产生元素函数
    def producer(que,num):
        for i in range(num):
            que.put(i)
            print('已放入数据:'+str(i))
            print(que.empty())
            print(que.qsize())
            time.sleep(1)
    
    
    #消费元素函数
    def consumer(que):
        while not que.empty():
            print('已取出数据:'+str(que.get()))
            time.sleep(1)
        else:
            print('队列已空,请加入元素再取出')
    
    
    q = queue.Queue(1)
    threading.Thread(target=producer, args=(q,10), name='producer').start()
    threading.Thread(target=consumer, args=(q,), name='consumer').start()
  • 相关阅读:
    mybatis中的动态语句中多条件or如何书写
    安装kibana的docker版
    安装elasticsearch的docker版
    git回滚push过的代码
    java中支付宝支付
    05 docker镜像删除
    远程仓库的搭建
    本地git工作流
    创建本地仓库
    git安装
  • 原文地址:https://www.cnblogs.com/gudanaimei/p/14408858.html
Copyright © 2011-2022 走看看