day37

队列

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() # 标记事件已经发生了


def connect_server():
   boot_event.wait() # 等待事件发生
   print("链接服务器成功!")

t1 = Thread(target=boot_server)
t1.start()

t2 = Thread(target=connect_server)
t2.start()


协程(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")
   # gevent.sleep(3)
   time.sleep(3)
   print("task1 over")

def task2():
   print(current_thread(),2)
   print("task2 run")
   print("task2 over")

# spawn 用于创建一个协程任务
g1 = gevent.spawn(task1)
g2 = gevent.spawn(task2)

gevent.joinall([g1,g2])
print("over")

猴子补丁

'''
本质就是把原本阻塞的代码 悄悄换成非阻塞代码  

例如 Queue.get(block=false)

当执行get而取不到值时 会抛出异常 只需捕获异常 然后在发生时切换到其他任务 就可以实现遇到IO 切换任务  

最终的解决方案

多进程 +单线程 + 协程



如果还是扛不住:

1.集群   所有服务器干的活都一样

2.分布式   每个服务器就干某个活    



'''


原文地址:https://www.cnblogs.com/zhuqihui/p/10986886.html