python 队列

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

队列类型

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

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

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

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

队列的操作

put 入队

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

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

get 出队

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

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

get_nowait 出队

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

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

join / task_done

join 可以等待队列完成(为空)

task_done 可以将一个任务置成已完成的状态。

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

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

i.e.

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()

output:

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

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

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

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

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

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

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

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

全做完了!
posted @   wztshine  阅读(1054)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示