如何在python的Threadpoolexecutor中运行async函数



我有一个asyncget_forecastweather函数,它给了我JSON天气数据,我知道我们不能在同步内执行异步函数,但我如何在一个单独的线程内执行,需要帮助,提前感谢

def weather_detail(request):
if request.method == 'GET':
city_name = 'my_city'
key = 'mykey'
result = None
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
response = executor.submit(get_forecastweather,city_name,key)
result = response.result()
print('Result from thread ',result)
return render(request,'weather/weather_detail.html')

我得到的错误是

RuntimeWarning: coroutine 'get_forecastweather' was never awaited
response = wrapped_callback(request, *callback_args, **callback_kwargs)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

您可以编写一个小包装器函数,在单独的线程中运行异步例程并返回结果。你可以简单地用asyncio.run。ThreadPoolExecutor机制将为您创建新的线程,asyncio.run方法将创建一个新的事件循环,运行它,返回结果,然后关闭循环。下面是一个示例程序,其中我生成一个介于两个限制之间的随机整数,而不是您对天气的请求:

from concurrent.futures import ThreadPoolExecutor
import random
import time
import asyncio
# You would use weather_detail here
async def get_random(n0, n1):
await asyncio.sleep(3.0)
return random.randint(n0, n1)
def wrapper(coro):
return asyncio.run(coro)
def main():
print("Start", time.ctime())
with ThreadPoolExecutor(max_workers=3) as executor:
arglist = ((10, 20), (30, 40), (50, 60), (90, 100))
coros = [get_random(n0, n1) for n0, n1 in arglist]
for r in executor.map(wrapper, coros):
print(r, time.ctime())

main()
# Output:
# Start Fri Sep 10 00:45:13 2021
# 15 Fri Sep 10 00:45:16 2021
# 40 Fri Sep 10 00:45:16 2021
# 52 Fri Sep 10 00:45:16 2021
# 99 Fri Sep 10 00:45:19 2021

我包含了时间戳来显示时间延迟,并证明三个线程并行运行。对包装器的前三个调用在3秒内完成,但第四个调用需要3秒,因为只有三个工作线程。

最新更新