#线程:单线程下的并发就叫协程 # 引子:单线程下的并发,yield还记得不,也叫协程,但是意义不大,效率不高 # 如果是纯计算类型,你并发,会浪费时间,效率不高 # 所以我们要解决这个问题,遇到计算咋办,遇到IO咋办 # def producer(): # g = consumer() # print(next(g)) # for i in range(10): # g.send("商品%s"%(i)) # pass # def consumer(): # while True: # data = yield # print("消费者收到%s"%(data)) # if __name__ == "__main__": # producer() #目的:为了较少IO,让线程变为计算密集型,从而分配cpu执行,提高效率 # 优点如下: # # 1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 # 2. 单线程内就可以实现并发的效果,最大限度地利用cpu # 缺点如下: # # 1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程 # 2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程 # 总结协程特点: # # 必须在只有一个单线程里实现并发 # 修改共享数据不需加锁 # 用户程序里自己保存多个控制流的上下文栈 # 附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制)) # yield greenlet 都没有实现 都不重要 # from greenlet import greenlet # # def eat(name): # print("%s eat 1"%(name)) # g2.switch("wusen") # print("%s eat 2"%(name)) # g2.switch() # def play(name): # print("%s play 1"%(name)) # g1.switch() # print("%s play 2"%(name)) # # if __name__ == "__main__": # g1 = greenlet(eat) # g2 = greenlet(play) # g1.switch("wusen") #嘿嘿这是正题 # from gevent import monkey;monkey.patch_all() # 监控程序下所有的IO 一定要在文件的开头 # import gevent,time # # def eat(name): # print("%s eat 1"%(name)) # gevent.sleep(3) # print("%s eat 2"%(name)) # gevent.sleep(5) # # def play(name): # print("%s play 1"%(name)) # gevent.sleep(8) # # print("%s play 2"%(name)) # # if __name__ == "__main__": # #这两个是异步提交 # g1 = gevent.spawn(eat,"wusen") # g2 = gevent.spawn(play," 3ξ") # # #方法一 # g1.join() # g2.join() # # # 方法二 # gevent.joinall([g1,g2]) # 怎么玩呢,多进程下多线程全局协程,那你就牛逼了,效率就很快了
View Code
协程结构:
1.yield
2.greenlet
3.gevent
第三个才是重点:原理,让程序内部变成计算型,从而抢cpu,
from gevent import monkey;monkey.patch_all() # 监控程序下所有的IO 一定要在文件的开头 import gevent,time def eat(name): print("%s eat 1"%(name)) gevent.sleep(3) print("%s eat 2"%(name)) gevent.sleep(5) def play(name): print("%s play 1"%(name)) gevent.sleep(8) print("%s play 2"%(name)) if __name__ == "__main__": #这两个是异步提交 g1 = gevent.spawn(eat,"wusen") g2 = gevent.spawn(play," 3ξ") #方法一 g1.join() g2.join() # 方法二 gevent.joinall([g1,g2])