异步化框架一部分
- 异步非阻塞、asyncio
- tornado、fastapi、django3.x asgi、aiohttp都在异步化 -->提升性能
协程详解
- 协程不是计算机提供,程序员认为创造。
- 协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。
- 简而言之:其实就是通过一个线程实现代码块相互切换执行。
- 协程意义:在一个线程中如果遇到IO等待时间,线程不会傻傻等,利用空闲时间去干其他事
实例:
def fun1(): #如果按正常思路来执行的话
print(1)
print(2) #程序会先执行fun1()、再次执行fun2()
def fun2():
print(3)
print(4) #(核心)
#协程意思就是在fun1()和fun2()中来回切换的执行
fun1() #当然协程只有一个线程来完成这个事情
fun2()
输出结果为: 1
2
3
4
Python中实现协程的几种方法:
- greenlet 这是一个第三方模块,也是一个早期的模块
- yield 关键字实现
- asyncio装饰器(py3.4版本以上)
- async、await关键字(py3.5以上【推荐】)
通过greenlet实现协程
pip install greenlet -i https://pypi.doubanio.com/simple --安装模块
from greenlet import greenlet --导入模块
def fun1():
print(1) -- 第二步: 输出 1
gr2.switch() -- 第三步:执行 gr2 (也就是func2函数)
print(2) -- 第六步:输出 2
gr2.switch() -- 第七步:执行 gr2 (也就是func2函数)
def fun2():
print(3) -- 第四步:输出 3
gr1.switch() -- 第五步:执行 gr1 (也就是fun1函数)
print(4) -- 第八步:输出 4
gr1 = greenlet(fun1)
gr2 = greenlet(fun2)
gr1.switch() -- 第一步:去执行 func1 函数
输出为: 1
3
2
4
#如此执行,就实现了一个线程在函数中来回切换执行的方式.也就是协程
通过yield关键字实现协程
def fun1():
yield 1
yield from fun2() -- 当调用fuc1()函数时,执行到这里,会执行fuc2函数 ↓
yield 2 -- 等func2函数执行完毕,跳回刚才跳出的位置,继续执行fuc1
def fun2():
yield 3
yield 4
f1 = fun1() 或 # f = fun1()
for item in f1: # print(next(f))
print(item) # print(next(f))
# print(next(f))
输出为:1 # print(next(f))
3
4
2
#这种方式是伪造的协程,不推荐使用,但是也实现了协程的定义
通过asyncio模块实现(python3.4版本之后的标准库)
import asyncio
@asyncio.coroutine #打上这个装饰器,才能是协程函数
def fun1():
print(1)
yield from asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中其他任务
print(2)
@asyncio.coroutine
def fun2():
print(3)
yield from asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中其他任务
print(4)
tasks = [
asyncio.ensure_future(fun1()),
asyncio.ensure_future(fun2()) #列表中是来回切换的函数
]
loop = asyncio.get_event_loop()
loop.run_until_complete(fun1())
#注意遇到IO阻塞 自动切换(python3.5之后推荐使用关键字)
async & await 关键字实现协程(Python3.5版本之后)
import asyncio
async def fun1():
print(1)
await asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中其他任务
print(2)
async def fun2():
print(3)
await asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中其他任务
print(4)
tasks = [
asyncio.ensure_future(fun1()),
asyncio.ensure_future(fun2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(fun1())
#注意遇到IO阻塞 自动切换