协程介绍前戏协程切换手动协程切换自动
Posted staff
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了协程介绍前戏协程切换手动协程切换自动相关的知识,希望对你有一定的参考价值。
一、协程简介、引子
‘‘‘ 协程:异步IO,队列,缓存 nginx效率高就是用了异步IO 协程是一种用户态的轻量级线程。又称微线程,怎么理解呢?后面会说 CPU只认识线程,不会像线程一样吧上下文保存在CPU寄存器,协程是用户控制的。 协程能保留上一次调用时的状态,单线程下实现并发效果 协程的好处: 1、无需线程上下文切换的开销,用yield的时候,只是在函数之间来回切换 2、无需原子操作锁定及同步的开销,没有异步锁之类的东西,因为协程就是单线程 3、方便切换控制流,简化编程模型 4、高并发-高扩展-低成本,一个CPU支持上万个协程都不成问题 缺点: 1、由于是单线程的无法利用多核资源,协程本质上是单线程, 2、协程需要和进程配合才能运行在多CPU上, 3、协程阻塞时会阻塞整个程序 ‘‘‘ # 回顾:自己之前写的yield协程,如果生产者里面sleep(1)秒速度变慢,可以理解,看下面 # 假设下面是Nginx,来了3个请求,请求切换应该在读数据库IO的地方切换 import time def home(): print("home") time.sleep(3) # 读数据库 print("home_end") def bbs(): print("bbs") time.sleep(2) # 读数据库 print("bbs_end") def login(): print("login") time.sleep(1) # 写数据库 print("login_end") ‘‘‘ 协程之所以能处理大并发,因为遇到IO操作就切换,因为IO耗时 那么什么时候切回去呢??应该是IO完成就切回去。怎么让系统知道IO操作完了呢?? ‘‘‘
二、协程切换手动挡
‘‘‘ 需要安装gevent ps:gevent是自动挡,由于自动挡封装了手动挡 安装gevent之后,就自动有greenlet greenlet是手动切换 ‘‘‘ from greenlet import greenlet def test1(): print(12) gr2.switch() print(34) gr2.switch() def test2(): print(56) gr1.switch() print(78) gr1 = greenlet(test1) # 启动一个协程 gr2 = greenlet(test2) gr1.switch() # 类似于yield语句 ‘‘‘ 12 56 34 78 ‘‘‘
三、协程切换自动挡
import gevent ‘‘‘ 如果是time.sleep()就变成串行的了 ‘‘‘ def foo(): print("foo_begin") gevent.sleep(2) print("foo_end") def bar(): print("bar_begin") gevent.sleep(1) print("bar_end") def func(): print("func_begin") gevent.sleep(0) print("func_end") gevent.joinall([gevent.spawn(foo), gevent.spawn(bar), gevent.spawn(func)]) ‘‘‘ foo_begin bar_begin func_begin func_end bar_end foo_end ‘‘‘
以上是关于协程介绍前戏协程切换手动协程切换自动的主要内容,如果未能解决你的问题,请参考以下文章