python学习——python的队列
- 队列的实现和方法
-
- 方法
- 先进先出的代码实现
- 后进先出的代码实现
- 优先级队列
- 例题
- python的Queue模块中提供了同步、线程安全的队列
- 包括FiFO(先入先出)、LIFO(后入先出)、优先级队列
- 这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现进程间的同步
队列的实现和方法
- 需要导入模块:
import queue
或者from queue import Queue
- 需要创建对象:
q = queue.Queue()
或者Q = Queue()
(使用from导入之后才能用)
- 创建队列的时候,需要向Queue中设置参数,表示队列的长度;不传参数,表示可以无限往队列中添加数据
方法
qsize()
,返回当前队列中包含的消息数量
empty()
,如果队列为空,返回True,或者False
full()
,如果队列满了,返回True或者False
get()
,获取队列,timeout参数可以设置等待时间
get_nowait()
,相当于get方法
put()
,写入队列,其中存在三个参数
-
-
-
- timeout=None,表示等待时间,默认None
put_nowait()
,相当于put方法
-
task_done()
,在完成一项工作之后,使用这个方法向队列发出一个信号,表示该任务执行完毕
join()
,实际上分意味着等到队列中所有任务执行完毕之后,再往下继续执行,否则就一直等待
-
- 注意:join的的判断依据,不仅仅是指队列中没有数据,数据get出去之后,要使用task_done发送一个信号,表示任务执行完毕
-
- task_done执行必须在join之前,且task_done执行的次数要大于等于任务个数,例如插入三次或者获取数据三次,就要写三条语句,否则会在join处阻塞,取法向下运行
先进先出的代码实现
import queue
q = queue.Queue(3)
for i in range(10,7,-1):
q.put(i)
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get())
print("队列元素:",q.get())
print("队列元素:",q.get())
print("获取完,队列是否为空:",q.empty())
q.task_done()
q.task_done()
q.task_done()
a = q.join()
print("join的执行结果:",a)
***********run_result***********
num: 3
is null: False
是否满队列: True
队列元素: 10
队列元素: 9
队列元素: 8
获取完,队列是否为空: True
join的执行结果: None
后进先出的代码实现
- 后进先出,需要使用LifoQueue方法,代码如下
from queue import LifoQueue
q = LifoQueue(3)
for i in range(10,7,-1):
q.put(i)
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get())
print("队列元素:",q.get())
print("队列元素:",q.get())
print("获取完,队列是否为空:",q.empty())
q.task_done()
q.task_done()
q.task_done()
a = q.join()
print("join的执行结果:",a)
优先级队列
- 插入元素的时候要插入元组,(优先级,数据)
- 获取数据的时候,按照优先级的大小,从小到大获取
from queue import PriorityQueue
q = PriorityQueue(3)
data = {2:5,0:10,1:6}
for k,v in data.items():
q.put((k,v))
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:", q.get())
print("队列元素:", q.get())
print("队列元素:",q.get())
print("获取完,队列是否为空:",q.empty())
q.task_done()
q.task_done()
q.task_done()
a = q.join()
print("join的执行结果:",a)
***************run_result***************
num: 3
is null: False
是否满队列: True
队列元素: (0, 10)
队列元素: (1, 6)
队列元素: (2, 5)
获取完,队列是否为空: True
join的执行结果: None
例题
- 1,使用一个队列来存储商品
- 2,创建一个专门生产圣品的线程类,当商品数量小于50时,开始生产商品
- 每次生产200个商品,每生产一轮,暂停1s
- 3,创建一个专门消费商品的线程类,当商品数量大于10时,开始消费
- 循环消费,每次消费3个,当商品个数小于10时,暂停2s
- 4,创建一个线程生产商品,5个线程消费商品
import threading
from queue import Queue
import time
q = Queue()
class Product(threading.Thread):
""" 生产者线程类 """
def run(self):
count = 0
while True:
if q.qsize() <50:
for i in range(200):
count+=1
goods = "第{}个商品".format(count)
q.put(goods)
print("生产:",goods)
time.sleep(2)
class Consumer(threading.Thread):
""" 消费者线程类 """
def run(self):
while True:
if q.qsize() >10:
for i in range(3):
a = q.get()
print(" 获得商品:", a)
else:
time.sleep(2)
p = Product()
p.start()
for i in range(5):
c = Consumer()
c.start()
import threading
from queue import Queue
import time
q = Queue()
class ProAndCons:
def product_goods(self):
while True:
print(q)
if q.qsize()<50:
for i in range(200):
goods = "第{}个元素".format(i)
q.put(goods)
print("goods:",goods)
time.sleep(2)
def cons_goods(self):
while True:
print(q)
print(q.qsize())
if q.qsize() >=10:
for i in range(3):
g = q.get()
print("商品:",g)
else:
time.sleep(2)
t = threading.Thread(target=ProAndCons().product_goods)
t.start()
time.sleep(10)
for i in range(5):
print("11")
c = threading.Thread(target=ProAndCons().cons_goods)
c.start()