1. 说明:
线程的缺点:在Python解释器中有一个GIL锁 — Global Interpreter Lock,在Python中的线程执行前都会获得这个GIL锁,每次执行100条字节码后,解释器就自动释放这个GIL锁,让别的线程有机会执行。Python会把所有的线程都加上这把锁,然后多线程之间只能交替执行,并未实现真正的并发执行。
使用协程可以避免,相当于异步编程
async关键字用于定义异步函数
await关键字用于等待异步函数执行(可等待对象包括:协程对象,Task对象,Future对象)
2. 简单使用:
# 引入协程包
import asyncio
import time
def demoAsync():
# 使用async修饰普通函数,可将普通函数变成异步函数
async def task1():
print("Execute the first task...")
# 耗时操作使用await修饰,这样会随机进入下一个协程函数执行
await asyncio.sleep(3)
print("the first task is done....")
async def task2():
print("Execute the second task...")
await asyncio.sleep(3)
print("the second task is done...")
async def task3():
print("Execute the third task...")
await asyncio.sleep(3)
print("the third task is done...")
# 创建任务事件循环
loop = asyncio.get_event_loop()
# 将异步任务加入到一个列表中,形成任务列表
tasks = [task1(), task2(), task3()]
# 开始任务事件循环,直到最后一个任务执行结束
loop.run_until_complete(asyncio.wait(tasks))
# 最后一个任务执行结束后,关闭循环
loop.close()
def demoNormal():
def task1():
print("Execute the first task...")
# 耗时操作使用await修饰,这样会随机进入下一个协程函数执行
time.sleep(3)
print("the first task is done....")
def task2():
print("Execute the second task...")
time.sleep(3)
print("the second task is done...")
def task3():
print("Execute the third task...")
time.sleep(3)
print("the third task is done...")
task1()
task2()
task3()
if __name__ == '__main__':
startAsync = time.time()
demoAsync()
endAsync = time.time()
# 用了异步执行,大概使用3s左右的时间 Async Time:3.0043070316314697
print(str("Async Time:" + str(endAsync - startAsync)))
startNormal = time.time()
demoNormal()
endNormal = time.time()
# 不用异步,则打印出来的时间应该时9s左右 Normal time:9.009456157684326
print(str("Normal time:" + str(endNormal - startNormal)))
3. Task对象:
Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行,此函数一次只能添加一个协程任务到事件循环种,使用**asyncio.gather(协程对象1,协程对象2,…)**可以一次加入多个协程任务到事件循环种。
注意:asyncio.create_task() 函数在 Python 3.7 中被加入,本质上是将协程对象封装成task对象,并将协程立即加入事件循环,同时追踪协程的状态。
import asyncio
async def func():
print(1)
await asyncio.sleep(2)
print(2)
return "返回值"
async def main():
print("main开始")
# 创建协程,将协程函数加入到事件循环中,处于就绪状态,还未执行。
task1 = asyncio.create_task(func())
# 使用 gather 函数可以一次性将多个协程函数加入事件循环中。
task2 = asyncio.gather(func(), func(), func())
print("main结束")
# 当执行某协程遇到IO操作时,会自动化切换执行其他任务。
# 此处的await是等待相对应的协程全都执行完毕并获取结果
ret1 = await task1 # task1 执行完之后,再执行下面的代码
ret2 = await task2
print(ret1, ret2)
asyncio.run(main()) # 使用run()方法启动协程任务执行,在python3.7的版本能够使用这种方式
持续更新中,请大家多多关注…