Python中的queue和collections库中都有队列的实现。queue实现的队列主要用于多线程编程,而collections中的deque实现的队列则用于高性能的单线程情况下的队列操作。
queue库中的queue.Queue是一个线程安全的队列,可以实现多个线程之间的数据共享,其内部实现使用了锁机制来保证线程安全。queue模块提供了3种队列模式:先进先出(FIFO)、后进先出(LIFO)和优先级队列(优先级越高越先出队)。queue.Queue的常用方法包括put()、get()、put_nowait()、get_nowait()、task_done()和join()。
示例1:实现多线程获取网页数据并存入队列中
import threading
import queue
def download_webpage(queue):
for url in ["url1", "url2", "url3"]:
data = "<html>data for %s</html>" % url
queue.put(data)
def parse_webpage(queue):
while True:
data = queue.get()
# 解析数据
queue.task_done()
q = queue.Queue()
t1 = threading.Thread(target=download_webpage, args=(q,))
t2 = threading.Thread(target=parse_webpage, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()
collections中的deque是一个双端队列,可以在队列的两端进行插入和删除操作,deque是线程不安全的,因此在多线程环境中需要自行使用锁来保证线程安全。deque支持与list相同的操作,包括append()、appendleft()、pop()、popleft()、extend()、extendleft()等。
示例2:使用deque实现贪吃蛇游戏
from collections import deque
import random
# 初始化蛇头和蛇身位置
snake = deque([(0, 0)])
# 初始化蛇的长度
snake_len = 1
# 随机生成食物位置
food = (random.randint(0, 4), random.randint(0, 4))
# 移动蛇的位置
def move_snake(direction):
# 计算蛇头新位置
head = snake[-1]
if direction == "up":
new_head = (head[0] - 1, head[1])
elif direction == "down":
new_head = (head[0] + 1, head[1])
elif direction == "left":
new_head = (head[0], head[1] - 1)
elif direction == "right":
new_head = (head[0], head[1] + 1)
# 判断蛇头新位置是否合法
if new_head[0] < 0 or new_head[0] > 4 or new_head[1] < 0 or new_head[1] > 4:
return False
# 判断蛇头新位置是否与蛇身重合
if new_head in snake:
return False
# 完成移动
snake.append(new_head)
# 判断是否吃到食物
if new_head == food:
global snake_len, food
snake_len += 1
food = (random.randint(0, 4), random.randint(0, 4))
else:
snake.popleft()
return True