队列
from queue import Queue,Lifoqueue,PriorityQueue
q = Queue()
q.put()
q.get()
q.task_done()
q.join()
'''
和进程间通讯的Queue队列一样,task_done表示任务完成得信号,但是并不会关心是否获取了队列中得数据
不管是否被get(),只要调用了task_done(),join就不会等待
'''
pq = PriorityQueue()
pq.put((1,1,3))
pq.put((1,2,4))
print(pq.get())
'''
带有优先级得队列,优先级得算法是从小到大,如果传入一个容器如(元组),那么就会依次比对元组每个值得大小,
如果传入得元组内值都一样,没有大小区别,那么取出得是哪个我也不知道
'''
lq = LifoQueue()
lq.put((-1,))
lq.put((0,))
print(lq.get())
'''
先进后出队列
'''
事件(Event)
'''
事件,表示发生了某件事情,我们可以去关注某个事件然后采取一些行动 本质上事件是用来线程间通讯的 ,用于状态同步
'''
import threading import Thead,Event
boot_event = Event()
boot_event.clear() 回复事件的状态为False
boot_event.is_set() 返回事件的状态
boot_event.wait()等待事件发生 ,就是等待事件被设置为True
boot_event.set() 设置事件为True
def boot_server():
print("正在启动服务器......")
time.sleep(3)
print("服务器启动成功!")
boot_event.set()
协程(gevent)
'''
协程 翻译为轻量级线程 ,也称之为微线程,是应用程序级别的任务调度方式
应用程序级别调度:我可以在检测到I/O操作时,立马切换到我的其他任务来执行
如果有足够的任务来执行,就可以把CPU的时间片充分利用起来
操作系统级别调度:遇到IO操作系统就会拿走CPU, 下一次分给哪个进程就不得而知了
咱们使用Cpython 到底如何提高效率
在Cpython中有GIL锁 导致多线程不能并行执行丧失了 多核优势,
即使开启了多线程也只能并发, 这时候完全 可以使用协程来实现并发
优点:不会占用更多无用的资源
缺点:如果是计算任务 使用协程反而降低效率
gevent 不具备检测IO的能力 需要为它打补丁 打上补丁之后就能检测IO
注意补丁一定打在最上面 必须保证导入模块前就打好补丁
任务要执行,必须保证主线程没挂 因为所有协程任务都是主线在执行 ,必须调用join来等待协程任务
理论上等待执行时间最长的任务就行 , 但是不清楚谁的时间长 可以全部join
'''
from gevent import monkey
monkey.patch_all()
from threading import current_thread
import gevent,time
def task1():
print(current_thread(),1)
print("task1 run")
猴子补丁
'''
本质就是把原本阻塞的代码 悄悄换成非阻塞代码
例如 Queue.get(block=false)
当执行get而取不到值时 会抛出异常 只需捕获异常 然后在发生时切换到其他任务 就可以实现遇到IO 切换任务
最终的解决方案
多进程 +单线程 + 协程
如果还是扛不住:
1.集群 所有服务器干的活都一样
2.分布式 每个服务器就干某个活
'''