python3中async使用run_in_executor构建异步task及functools传参
python3中async使用run_in_executor构建异步task及functools传参
代码示例:
import asyncio
import functools
import threading
import time
import requests
def request_download_img(url, param1, param2):
print("request_download_img:", time.time(), url, param1, param2)
time.sleep(5)
response = requests.get(url)
# 图片保存到本地文件
file_name = url.rsplit('_')[-1]
with open(file_name, mode='wb') as file_object:
file_object.write(response.content)
async def create_async_task(url, param1, param2):
loop = asyncio.get_event_loop()
# 使用run_in_executor将同步函数构建异步task
future = loop.run_in_executor(None, functools.partial(
request_download_img,
url=url,
param1=param1,
param2=param2,
))
# 避免 coroutine was never awaited
await future
def run_sync():
url_list = [
'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
'https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg',
'https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg'
]
task1 = create_async_task(url_list[0], param1="a", param2="b")
task2 = create_async_task(url_list[0], param1="a", param2="b")
task3 = create_async_task(url_list[0], param1="a", param2="b")
tasks = [task1, task2, task3]
# 执行多个异步任务
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print("tasks", tasks)
if __name__ == '__main__':
p1 = threading.Thread(target=run_sync, daemon=False)
p1.run()
解决async 运行多线程时报错 RuntimeError: There is no current event loop in thread 'Thread-2'
# 多线程-非主线程-事件控制
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
# new_event_loop 可以 close
loop.close()
参考:
https://www.cnblogs.com/cwp-bg/p/9590700.html
https://zhuanlan.zhihu.com/p/137057192
https://www.cnblogs.com/SunshineKimi/p/12053914.html