鱼C论坛

 找回密码
 立即注册
查看: 1994|回复: 5

[已解决]异步函数调用如何不阻塞后续进程?

[复制链接]
发表于 2021-11-14 23:46:02 | 显示全部楼层 |阅读模式
50鱼币
本帖最后由 白two 于 2021-11-15 12:06 编辑

我有一个异步函数,在里面再定义了一个异步函数
async def run():
    async def call_async_sleep():
            await asyncio.sleep(19)
            try:
                await driver.close()
            except:
                pass

    call_async_sleep()
    ......
我需要只要一开始,里面的那个函数就会执行,但是不会阻碍后面函数的执行,然后不管最后结果如何(因为后续操作容易出bug,但是想做一个统一的处理方式),都会执行这个函数内的操作

但它报错:
RuntimeWarning: coroutine 'run.<locals>.call_async_sleep' was never awaited
加上 await 的话就会先等这个函数执行完,再执行后面的操作,但我需要的是它不会阻碍后面函数的运行
才接触异步,有哪个大佬能解决一下吗?
最佳答案
2021-11-14 23:46:03
本帖最后由 kogawananari 于 2021-11-15 00:42 编辑

coroutine 同一时间只能执行一个   future是注册了就可以托管运行的
无论是coroutine还是future都得await才行 不能直接执行  
除此之外还有一些API可以直接并发运行coroutine不需要自己去注册为future
其中最好用的应该是run_coroutine_threadsafe  他可以往你的进程里发送coroutine

我给出一个数据库查询的例子
"""数据库连接测试"""
from threading import Thread
import asyncio
from sqlalchemy import func, select
from db.models import Dictdata
from db import async_session_local


async def test_select():
    async with async_session_local() as dbs:
        total_orm = select(func.count(Dictdata.id)).where(Dictdata.is_active == 1)
        total: int = (await dbs.execute(total_orm)).scalar()
        print(total)


def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()


async def end_loop(timeout=15):
    await asyncio.sleep(timeout)
    loop = asyncio.get_event_loop()
    loop.stop()

new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()
asyncio.run_coroutine_threadsafe(test_select(), new_loop)
asyncio.run_coroutine_threadsafe(end_loop(3), new_loop)
t.join()
test_select 就是主函数  其他的你都不需要改 在里面写就行

最佳答案

查看完整内容

coroutine 同一时间只能执行一个 future是注册了就可以托管运行的 无论是coroutine还是future都得await才行 不能直接执行 除此之外还有一些API可以直接并发运行coroutine不需要自己去注册为future 其中最好用的应该是run_coroutine_threadsafe 他可以往你的进程里发送coroutine 我给出一个数据库查询的例子 test_select 就是主函数 其他的你都不需要改 在里面写就行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-14 23:46:03 | 显示全部楼层    本楼为最佳答案   
本帖最后由 kogawananari 于 2021-11-15 00:42 编辑

coroutine 同一时间只能执行一个   future是注册了就可以托管运行的
无论是coroutine还是future都得await才行 不能直接执行  
除此之外还有一些API可以直接并发运行coroutine不需要自己去注册为future
其中最好用的应该是run_coroutine_threadsafe  他可以往你的进程里发送coroutine

我给出一个数据库查询的例子
"""数据库连接测试"""
from threading import Thread
import asyncio
from sqlalchemy import func, select
from db.models import Dictdata
from db import async_session_local


async def test_select():
    async with async_session_local() as dbs:
        total_orm = select(func.count(Dictdata.id)).where(Dictdata.is_active == 1)
        total: int = (await dbs.execute(total_orm)).scalar()
        print(total)


def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()


async def end_loop(timeout=15):
    await asyncio.sleep(timeout)
    loop = asyncio.get_event_loop()
    loop.stop()

new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()
asyncio.run_coroutine_threadsafe(test_select(), new_loop)
asyncio.run_coroutine_threadsafe(end_loop(3), new_loop)
t.join()
test_select 就是主函数  其他的你都不需要改 在里面写就行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 09:58:32 | 显示全部楼层
kogawananari 发表于 2021-11-15 00:40
coroutine 同一时间只能执行一个   future是注册了就可以托管运行的
无论是coroutine还是future都得await ...

  我看他们直接是用task 来创建队列的,asyncio包里面有启动异步的,不需要用线程来启动。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 11:04:57 | 显示全部楼层
关注感兴趣的帖。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 21:26:44 | 显示全部楼层
z5560636 发表于 2021-11-15 09:58
我看他们直接是用task 来创建队列的,asyncio包里面有启动异步的,不需要用线程来启动。

task 是 future的子类  有什么问题吗 直接await task也是异步的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-16 13:01:14 | 显示全部楼层
kogawananari 发表于 2021-11-14 23:46
coroutine 同一时间只能执行一个   future是注册了就可以托管运行的
无论是coroutine还是future都得await ...

拜谢大佬,我再研究研究
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 19:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表