【问题标题】:coroutine was never awaited, async multithreading从未等待协程,异步多线程
【发布时间】:2020-10-21 14:15:49
【问题描述】:
async def existance(s, name):
    async with s.head(f"https://example.com/{name}") as r1:
        if r1.status == 404:
            print('wow i worked')

async def process(names):
    with ThreadPoolExecutor(max_workers=3) as executor:
        async with aiohttp.ClientSession() as s:
            loop = asyncio.get_event_loop()
            tasks = []
            for name in names:
                if len(name) >= 5 and len(name) < 16 and name.isalnum():
                    task = loop.run_in_executor(
                        executor,
                        existance,
                        *(s, name)
                        )
                    tasks.append(task)
            return await asyncio.gather(*tasks)

while True:
    start_time = time.time()
    loop = asyncio.get_event_loop()
    future = asyncio.ensure_future(process(names))
    loop.run_until_complete(future)

我正在使用上面的代码尝试将我创建的任务拆分为多个线程,同时异步检查它们。

我收到此错误:

RuntimeWarning: coroutine 'existance' was never awaited
  future = asyncio.ensure_future(process(names))

我还是一个 Python 初学者,我真的不知道我应该在这里改变什么以获得我想要的结果。 任何帮助表示赞赏,如果这是一个重复的问题,我很抱歉。

【问题讨论】:

  • run_in_executor 不需要协程,它需要普通函数。您正在尝试以一种行不通的方式混合多线程和异步。你应该要么使用线程池来做阻塞 IO,要么使用 asyncio 和协程。

标签: python-3.x python-asyncio python-multithreading aiohttp


【解决方案1】:

由于existance是异步的,你根本不需要线程,所以你可以像这样实现process

async def process(names):
    async with aiohttp.ClientSession() as s:
        tasks = []
        for name in names:
            if len(name) >= 5 and len(name) < 16 and name.isalnum():
                tasks.append(existance(s, name))
        return await asyncio.gather(*tasks)

如果existance 正在调用一些可能会阻塞事件循环的同步慢速函数(例如 BeautifulSoup 解析),您可以通过线程池运行 that 函数来解决此问题。像这样在本地引入run_in_executor

# instead of:
# result = slow_calculation(arg1, arg2)   # sync/slow code
# use this:
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, slow_calculation, arg1, arg2)

但不要尝试通过run_in_executor 调用async 函数,那是行不通的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2020-07-08
    • 2013-02-15
    相关资源
    最近更新 更多