队列概念
队列可以并发的分派多个线程,并按指定的顺序进行处理,把请求的数据放入队列容器中,线程不需要等待,当队列处理完数据后,线程再准时来取数据即可。请求数据的线程只与这个队列容器存在关系,处理数据的线程down掉不会影响到请求数据的线程,队列会派给其他线程处理这份数据,它实现了解耦,提高效率。当在多个线程或进程之间需要安全得交换信息或共享资源时,就需要使用队列。
Python四种类型的队列:
Queue
:FIFO 即 first in first out 先进先出LifoQueue
:LIFO 即 last in first out 后进先出PriorityQueue
:优先队列,级别越低,越优先deque
:双端队列
Queue常用方法
# -*- coding:utf-8 -*-
from queue import Queue
__author__ = 'Evan'
def queue_usage(put_data):
"""
Queue常用方法
:param put_data: 放入的数据,列表或元组类型
:return:
"""
q = Queue(maxsize=3) # 设置队列上限为3
for each in put_data:
print(f'添加({each})到队列')
q.put(each)
print(f'返回队列的大小: {q.qsize()}')
print(f'判断队列是否为空: {q.empty()}')
print(f'判断队列是否满了: {q.full()}')
while not q.empty():
print(f'取出:{q.get()}')
q.task_done() # 告诉队列,这个数据已经使用完毕
q.join() # 阻塞调用线程,直到队列中的所有任务被处理掉
if __name__ == '__main__':
queue_usage(put_data=[1, 2, 3])
输出结果:
添加(1)到队列
添加(2)到队列
添加(3)到队列
返回队列的大小: 3
判断队列是否为空: False
判断队列是否满了: True
取出:1
取出:2
取出:3
四种队列使用方法
1. Queue 先进先出队列
# -*- coding:utf-8 -*-
from queue import Queue
__author__ = 'Evan'
def fifo_queue(put_data):
"""
FIFO,先进先出队列
:param put_data: 放入的数据,列表或元组类型
:return:
"""
assert isinstance(put_data, (list, tuple)), '请传入列表或元组类型的put_data'
# maxsize为队列数据上限,小于或等于0则不限制,当容器数量大于这个数则阻塞,直到队列中的数据被消掉
q = Queue(maxsize=0)
# 依次写入队列数据
for each in put_data:
print(f'添加({each})到队列')
q.put(each)
print(f'当前队列所有数据:{q.queue}')
# 逐次取出所有数据
while not q.empty():
print(f'取出:{q.get()}')
print(f'当前队列所有数据:{q.queue}')
if __name__ == '__main__':
fifo_queue(put_data=[3, 2, 1])
输出结果:
添加(3)到队列
添加(2)到队列
添加(1)到队列
当前队列所有数据:deque([3, 2, 1])
取出:3
取出:2
取出:1
当前队列所有数据:deque([])
2. LifoQueue 后进先出队列
# -*- coding:utf-8 -*-
from queue import LifoQueue
__author__ = 'Evan'
def lifo_queue(put_data):
"""
LIFO,后进先出队列
:param put_data: 放入的数据,列表或元组类型
:return:
"""
assert isinstance(put_data, (list, tuple)), '请传入列表或元组类型的put_data'
# maxsize为队列数据上限,小于或等于0则不限制,当容器数量大于这个数则阻塞,直到队列中的数据被消掉
q = LifoQueue(maxsize=0)
# 依次写入队列数据
for each in put_data:
print(f'添加({each})到队列')
q.put(each)
print(f'当前队列所有数据:{q.queue}')
# 逐次取出所有数据
while not q.empty():
print(f'取出:{q.get()}')
print(f'当前队列所有数据:{q.queue}')
if __name__ == '__main__':
lifo_queue(put_data=[3, 2, 1])
输出结果:
添加(3)到队列
添加(2)到队列
添加(1)到队列
当前队列所有数据:[3, 2, 1]
取出:1
取出:2
取出:3
当前队列所有数据:[]
3. PriorityQueue 优先队列
# -*- coding:utf-8 -*-
from queue import PriorityQueue
__author__ = 'Evan'
def priority_queue(put_data):
"""
Priority,优先队列,级别越低,越优先
:param put_data: 放入的数据,列表或元组类型
:return:
"""
assert isinstance(put_data, (list, tuple)), '请传入列表或元组类型的put_data'
# maxsize为队列数据上限,小于或等于0则不限制,当容器数量大于这个数则阻塞,直到队列中的数据被消掉
q = PriorityQueue(maxsize=0)
# 依次写入队列数据
for each in put_data:
print(f'添加{each}到队列,优先级别为:{each[0]}')
q.put(each)
print(f'当前队列所有数据:{q.queue}')
# 逐次取出所有数据,按优先级获取
while not q.empty():
print(f'取出:{q.get()}')
print(f'当前队列所有数据:{q.queue}')
if __name__ == '__main__':
priority_queue(put_data=[(3, 'value1'), (1, 'value2'), (2, 'value3')])
输出结果:
添加(3, 'value1')到队列,优先级别为:3
添加(1, 'value2')到队列,优先级别为:1
添加(2, 'value3')到队列,优先级别为:2
当前队列所有数据:[(1, 'value2'), (3, 'value1'), (2, 'value3')]
取出:(1, 'value2')
取出:(2, 'value3')
取出:(3, 'value1')
当前队列所有数据:[]
4. deque 双端队列
# -*- coding:utf-8 -*-
from collections import deque
__author__ = 'Evan'
def deque_example(put_data):
"""
Deque,双端队列
:param put_data: 放入的数据,列表或元组类型
:return:
"""
assert isinstance(put_data, (list, tuple)), '请传入列表或元组类型的put_data'
# 放入数据到双端队列
dq = deque(put_data)
print(f'当前队列所有数据:{dq}')
# 增加数据到队左
dq.appendleft('aa')
print(f'当前队列所有数据:{dq}')
# 增加数据到队尾
dq.append('cc')
print(f'当前队列所有数据:{dq}')
print(f'移除队尾,并返回:{dq.pop()}')
print(f'移除队左,并返回:{dq.popleft()}')
print(f'当前队列所有数据:{dq}')
if __name__ == '__main__':
deque_example(put_data=['a', 'b', 'c'])
输出结果:
当前队列所有数据:deque(['a', 'b', 'c'])
当前队列所有数据:deque(['aa', 'a', 'b', 'c'])
当前队列所有数据:deque(['aa', 'a', 'b', 'c', 'cc'])
移除队尾,并返回:cc
移除队左,并返回:aa
当前队列所有数据:deque(['a', 'b', 'c'])
Over~