python 队列

Queue是python标准库中的线程安全的队列(FIFO)实现, 提供了一个适用于多线程编程的先进先出的数据结构

1. 三种队列出入方式:

先入先出、后入先出、优先级队列

# 普通队列,先入先出,maxsize=0意味着队列没有上限
q0 = queue.Queue(maxsize=2)

# last in first out,后入先出
q1 = queue.LifoQueue()

# 优先顺序队列,数值越小优先级越高,使用方法:q2.put(1,'name')
q2 = queue.PriorityQueue()

2. 队列的操作

1. 入队

  put:put方法是一个阻塞的方法,即如果设置了队列的大小,当队列已经满了,还继续put入队,会阻塞卡死

q0.put(1)         # 给队列放置一个内容;put是阻塞的方法,如果队列设置了上限,当超出队列长度时,会阻塞卡死
put_nowait: 此方法不是阻塞的方法,但是如果入队时超出队列大小,会报错:queue.Full
q0.put_nowait(3)  # 给队列放置一个内容;此方法不会阻塞,但是当超出队列设定的长度时会报错

2. 出队

get方法:get方法也是阻塞的方法,当队列为空时,会阻塞

# get方法获取队列的值,是阻塞的方法,当队列为空的时候,会阻塞卡死,每调用get一次,出队一个元素
print(q0.get())
print(q0.get())

get_nowait方法:不会阻塞,但是当队列为空时,会报错:queue.Empty

# 取值的方法,不会阻塞,但是会报错
print(q0.get_nowait())

3. 其他方法:

等待队列处理完毕:

# 当队列还有任务没有被处理时,会一直阻塞,直到队列中的 任务(put进去的东西) 全被处理掉(task_done)
q0.join()

# 结束一个任务
q0.task_done()
import queue

# 设置队列大小的上限 10
q = queue.Queue(maxsize=10)

# 放了两个元素进去
q.put(2)
q.put(3)

# task_done 和 queue放进去的元素数量有关。放进去多少个,就可以 task_done 多少次
q.get()  # 不用 get,也可以 q.task_done,队列判断任务有没有完成,和队列的元素数量无关,和 task_done 有关
q.get()
q.task_done()
q.task_done()
q.join()  # 上面执行两次 task_done 后,才会打印下面的 q.qsize。否则哪怕已经通过 q.get() 方法将队列拿空了,队列依然会认为任务没有完成,会一直阻塞
print(q.qsize())

队列是否满了或者空了:

# 判断队列是否满了或空了,如果是,返回True
print('Full:',q0.full())
print('Empty:',q0.empty())

查看队列大小:

# 队列大小
print(q0.qsize())

 生产者消费者模型:

import time
import threading
import queue

# 设置队列大小的上限 10
q = queue.Queue(maxsize=10)

def teacher(name):
    for i in range(20):
        q.put(1)   # 阻塞的方法,如果队列达到上限10,则等待着队列被其他线程get出队后再put
        print(f'{name} 发了一张试卷')
        time.sleep(2)
    print('-----------等待剩余试卷被做完...------------')
    q.join()  # 阻塞的方法,直到队列中的所有任务都被task_done
    print('全做完了!')


def studnet(name):
    while True:
        q.get()  # 出队一个任务,如果队列为空,则等待着,直到队列有值再取出
        print(f'{name} 做了一张试卷,还剩{q.qsize()}')
        time.sleep(5)
        q.task_done()  # 对出队的任务进行task_done

t = threading.Thread(target=teacher,args=('王老师',))

# threading.Timer(time,func,args,kwargs) 对一个线程延迟一个时间后再执行。
s = threading.Timer(3,studnet,args=('小明',))
s1 = threading.Timer(3,studnet,args=('小洪',))

t.start()
s.start()
s1.start()
王老师 发了一张试卷
王老师 发了一张试卷
小明 做了一张试卷,还剩1
小洪 做了一张试卷,还剩0

王老师 发了一张试卷
王老师 发了一张试卷
小明 做了一张试卷,还剩1
小洪 做了一张试卷,还剩0

王老师 发了一张试卷
王老师 发了一张试卷
王老师 发了一张试卷
小明 做了一张试卷,还剩2
小洪 做了一张试卷,还剩1

王老师 发了一张试卷
王老师 发了一张试卷
小明 做了一张试卷,还剩2
小洪 做了一张试卷,还剩1

王老师 发了一张试卷
王老师 发了一张试卷
王老师 发了一张试卷
小洪 做了一张试卷,还剩3
小明 做了一张试卷,还剩2

王老师 发了一张试卷
王老师 发了一张试卷
小洪 做了一张试卷,还剩3
小明 做了一张试卷,还剩2
王老师 发了一张试卷
王老师 发了一张试卷
王老师 发了一张试卷
小明 做了一张试卷,还剩4
小洪 做了一张试卷,还剩3

王老师 发了一张试卷
王老师 发了一张试卷
小洪 做了一张试卷,还剩4
小明 做了一张试卷,还剩3
王老师 发了一张试卷
-----------等待剩余试卷被做完...------------
小明 做了一张试卷,还剩3
小洪 做了一张试卷,还剩2

小明 做了一张试卷,还剩1
小洪 做了一张试卷,还剩0

全做完了!
原文地址:https://www.cnblogs.com/wztshine/p/11970048.html