3.5 Future对象
Task继承Future,Task对象内部await结果的处理是基于Future对象而来的。
示例1
import asyncio
async def main():
# 获取当前事件循环
loop = asyncio.get_running_loop()
# 创建一个任务(Future对象),这个任务什么都不干
fut = loop.create_future()
# 等待任务最终结果(Future对象),没有结果则会一直等下去
await fut
if __name__ == '__main__':
asyncio.run(main())
示例2
import asyncio
async def set_after(fut):
await asyncio.sleep(2)
fut.set_result('666')
async def main():
# 获取当前事件循环
loop = asyncio.get_running_loop()
# 创建一个任务(Future对象),没绑定任何行为,则这个任务永远不知道什么时候结束
fut = loop.create_future()
# 手动创建一个任务(Task对象),绑定了set_after函数,函数内部在2s之后,会给fut赋值。
# 即手动设置future任务的最终结果,那么fut就可以结束了
await loop.create_task(set_after(fut))
data = await fut
print(data)
if __name__ == '__main__':
asyncio.run(main())
3.5 concurrent.futures.Future对象
使用线程池、进程池实现异步操作时用到的对象。
import time
from concurrent.futures import Future
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures.process import ProcessPoolExecutor
def func(value):
time.sleep(1)
print(value)
return 123
# 创建线程池
pool = ThreadPoolExecutor(max_workers=5)
for i in range(10):
fut = pool.submit(func, i)
print(fut)
以下代码写代码可能会存在交叉时间。例如:crm项目80%都是基于协程异步编程+MySQL(不支持)【线程、进程做异步操作】。
import time
import asyncio
import concurrent.futures
def func1():
# 某个耗时操作
time.sleep(2)
return 'SB'
async def main():
loop = asyncio.get_running_loop()
# 1.Run in the default loop's executor(默认ThreadPoolExecutor)
# 第一步:内部会调用ThreadPoolExecutor的submit方法去线程池中申请一个线程去执行func1函数,并返回一个concurrent.futures.Future对象
# 第二步:调用asyncio.wrap_futures.Future将concurrent.futures.Future对象包装为asyncio.Future对象
# 因为concurrent.futures.Future对象不支持await语法,所以需要包装为asyncio.Future对象才能使用
fut = loop.run_in_executor(None, func1)
result = await fut
print('default thread pool', result)
# 2.Run in a custom thread
# with concurrent.futures.ThreadPoolExecutor() as pool:
# result = await loop.run_in_executor(pool, func1)
# print('custom thread pool', result)
# 3.Run in a custom process pool:
# with concurrent.futures.ProcessPoolExecutor() as pool:
# result = await loop.run_in_executor(
# pool, func1
# )
# print('custom process pool', result)
if __name__ == '__main__':
asyncio.run(main())