如何 运行 Threadpoolexecutor 中的异步函数 python
how to run async function in Threadpoolexecutor in python
我有一个异步 get_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
您可以编写一个小的包装函数,运行在单独的线程中作为您的异步例程,并 return作为结果。为此,您可以简单地使用 asyncio.run
。 ThreadPoolExecutor 机制将为您创建新的线程,asyncio.run
方法将创建一个新的事件循环,运行 它,return 结果然后关闭循环。这是一个示例程序,我生成一个介于两个限制之间的随机整数,而不是您对天气的请求:
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
我加入了时间戳以显示时间延迟,并证明三个线程 运行ning 是并行的。对包装器的前三个调用在 3 秒内完成,但第四个需要 3 秒以上,因为只有三个工作线程。
我有一个异步 get_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
您可以编写一个小的包装函数,运行在单独的线程中作为您的异步例程,并 return作为结果。为此,您可以简单地使用 asyncio.run
。 ThreadPoolExecutor 机制将为您创建新的线程,asyncio.run
方法将创建一个新的事件循环,运行 它,return 结果然后关闭循环。这是一个示例程序,我生成一个介于两个限制之间的随机整数,而不是您对天气的请求:
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
我加入了时间戳以显示时间延迟,并证明三个线程 运行ning 是并行的。对包装器的前三个调用在 3 秒内完成,但第四个需要 3 秒以上,因为只有三个工作线程。