鱼C论坛

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

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

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

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

  8.     call_async_sleep()
  9.     ......
复制代码

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

但它报错:
  1. 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

我给出一个数据库查询的例子

  1. """数据库连接测试"""
  2. from threading import Thread
  3. import asyncio
  4. from sqlalchemy import func, select
  5. from db.models import Dictdata
  6. from db import async_session_local


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


  12. def start_loop(loop):
  13.     asyncio.set_event_loop(loop)
  14.     loop.run_forever()


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

  19. new_loop = asyncio.new_event_loop()
  20. t = Thread(target=start_loop, args=(new_loop,))
  21. t.start()
  22. asyncio.run_coroutine_threadsafe(test_select(), new_loop)
  23. asyncio.run_coroutine_threadsafe(end_loop(3), new_loop)
  24. t.join()
复制代码

test_select 就是主函数  其他的你都不需要改 在里面写就行

最佳答案

查看完整内容

coroutine 同一时间只能执行一个 future是注册了就可以托管运行的 无论是coroutine还是future都得await才行 不能直接执行 除此之外还有一些API可以直接并发运行coroutine不需要自己去注册为future 其中最好用的应该是run_coroutine_threadsafe 他可以往你的进程里发送coroutine 我给出一个数据库查询的例子 test_select 就是主函数 其他的你都不需要改 在里面写就行
小甲鱼最新课程 -> https://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

我给出一个数据库查询的例子

  1. """数据库连接测试"""
  2. from threading import Thread
  3. import asyncio
  4. from sqlalchemy import func, select
  5. from db.models import Dictdata
  6. from db import async_session_local


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


  12. def start_loop(loop):
  13.     asyncio.set_event_loop(loop)
  14.     loop.run_forever()


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

  19. new_loop = asyncio.new_event_loop()
  20. t = Thread(target=start_loop, args=(new_loop,))
  21. t.start()
  22. asyncio.run_coroutine_threadsafe(test_select(), new_loop)
  23. asyncio.run_coroutine_threadsafe(end_loop(3), new_loop)
  24. t.join()
复制代码

test_select 就是主函数  其他的你都不需要改 在里面写就行
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

  我看他们直接是用task 来创建队列的,asyncio包里面有启动异步的,不需要用线程来启动。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 11:04:57 | 显示全部楼层
关注感兴趣的帖。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

task 是 future的子类  有什么问题吗 直接await task也是异步的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

拜谢大佬,我再研究研究
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-17 07:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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