协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。
因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
使用greenlet实现协程操作,greenlet需要手动进行切换
首先需要使用greenlet创建类似与堆栈空间,然后使用switch进行切换
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()
使用Gevent实现协程,无需手动切换,遇到IO操作就会进行切换
import gevent
def func1(num):
print('in func1',num)
gevent.sleep(1) #模仿IO操作
print('back func1')
def func2():
print('in func2')
gevent.sleep(2) #模仿IO操作
print('back func2')
def func3():
print('in func3')
gevent.sleep(3)
print('back func3')
gevent.joinall([
gevent.spawn(func1,1), #传参的方式
gevent.spawn(func3),
gevent.spawn(func2),
])
先执行func1,打印第一句后遇到IO操作切换到func3又遇到IO,再次切换到func2,遇到IO操作后由于没有可执行的函数,开始等待,func1最先可执行自动跳转到func1打印第二句,然后func2IO操作结束输出func2的第二句,最后func3才结束IO操作,所有func3的第二句最后打印
事件驱动模式:每次有一个事件发生的时候会首先存入到一个消息队列中,然后会有专门的函数循环不断的从队列中取出事件进行处理,执行完一个事件后一般会执行一个回调函数来告知当前事件处理完毕。
异步操作也算是一种事件驱动的模式,遇到IO操作的时候交个操作系统来执行,IO操作结束后会执行一个回调函数告知程序IO结束可继续执行