Python asyncio 启动问题求助

查看 51|回复 2
作者:ohayoo   
求助大佬们,本菜鸡非专业程序员,只会点皮毛,偶尔做个小工具都是网上抄代码,东拼西凑,现在遇到一个这样的问题不知道怎么解决,还望大佬们能帮忙看看。
我的异步函数第一种方式启动,可以正常运行,但我现在想要换成第二种启动方式,就会报错 This event loop is already running ,可能有大佬想问,第一种方式可以正常跑就行了,为啥非要作死换成第二种呢?是因为 fastapi 的路由函数是异步的,我需要在路由函数里面调用前面这个 ip 查询的异步函数,所以模拟了这样一段代码前来求助。
想问下要怎么改才能在 aaa 这个异步函数里面启动前面的 main 函数呢?
import aiohttp
import asyncio
iplist = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
result = {}
async def get_ipinfo(ip, domain, sem):
    params = {'ip': ip, 'dns': domain}
    async with sem:
        async with aiohttp.ClientSession() as session:
            async with session.get('http://www.abc.com/', params=params) as resp:
                res = await resp.text()
                #res 结果写入全局变量字典中,代码省略
async def main(domain, sem):
    tasks = [get_ipinfo(ip, domain, sem) for ip in iplist]
    await asyncio.gather(*tasks)
################   启动方式 1  ##############
#上面的异步函数启动方式 1 ,可以正常运行
if __name__ == "__main__":
    sem = asyncio.Semaphore(20)
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main('www.test.com', sem))
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()
    print(result)
####################   启动方式 2  #####################
#上面的异步函数启动方式 2 ,报错
#     raise RuntimeError('This event loop is already running')
# RuntimeError: This event loop is already running
#
# During handling of the above exception, another exception occurred:
async def run(domain):
    sem = asyncio.Semaphore(20)
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main(domain, sem))
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()
async def aaa(domain):
    await run(domain)
    print(result)
asyncio.run(aaa('www.test.com'))

domain, SEM, Async, 函数

jenlors   
第二种方式,run 里面就不用再用 run_until_complete 的方式了,直接 await
karlkor   
在 async 函数里面执行 coroutine 可以使用 asyncio.create_task, 也就是说在你的第二个 case 里面用 asyncio.create_task 替换掉 loop.run_until_complete
您需要登录后才可以回帖 登录 | 立即注册

返回顶部