并发编程(四) 队列
六 队列
队列与线程有关,保证多线程信息交换的安全。另外,队列是一种数据结构。
队列可以解决的两个问题:解耦、异步
异步、同步:
异步:
优点:解决排队问题
缺点:不能保证任务被及时执行
应用场景:去哪儿网购机票
同步:
优点:保证任务被及时执行
缺点:排队问题
解耦:
消息队列天然解耦
进程通过消息队列联系,不需要有接口
6.1 队列的作用
- 存储消息和数据
- 保证消息顺序
- 保证数据交付
实际应用:
-
大并发:
目前使用web nginx(同一时刻,可以有1w-2w个并发请求);之前使用的是apache(同一时刻,只能有1000-2000个并发请求)
pv = page visit (页面访问量),pv上亿才算大并发,10 server web cluster集群可以满足需求
uv = user visit (每日独立用户量)
qps = 每秒查询率 -
生产者消费者模型
分布式:是一种工作方式,一堆机器,每个机器承担一部分运算
6.2 queue
python中创建队列的语法是queue.Queue()
,默认是先进先出队列(FIFO)。
import queue
q = queue.Queue()
q.put('ddd') # 队列中放入数据
q.qsize() # 显示队列大小
q.get() # 从队列中取数据
get与put方法
import queue
q = queue.Queue() #创建队列对象q
q.put(123) #将123放入队列中
q.put('hello')
q.get() #将第一个值从队列中取出
join和task_done方法
join()
阻塞进程,直到所有任务都完成,需要配合另一个方法task_done()
。
task_done()
表示某个任务完成。每一条get语句后需要一条task_done。
import queue
q = queue.Queue(5)
q.put(10)
q.put(20)
print(q.get())
q.task_done()
print(q.get())
# q.task_done() # 导致进程无法结束
q.join() # 阻塞进程
print("ending!")
其他模式
先进后出:queue.LifoQueue()
后进先出(LIFO)
优先级:queue.PriorityQueue()
优先级高先出
q.put([1,‘123’]) #1为有限等级,越小幼衔接
6.3 生产者消费者模型
通过容器解决生产者和消费者的强耦合性
import queue
import time
import threading
q = queue.Queue(5)
def maker():
while True:
q.put(1, block=1)
print('厨师做1个包子,库存:%s' % q.qsize())
time.sleep(1)
def com():
while True:
q.get()
print('顾客吃1个包子')
time.sleep(3)
t1 = threading.Thread(target=maker)
t2 = threading.Thread(target=com)
# t3 = threading.Thread(target=com)
t1.start()
t2.start()
t3.start()