python3 asyncio 如何开启一个不 await 的协程 的问题

2019-10-15 10:01:02 +08:00
 dafsic

用 aiohttp 框架,当一个 web 请求过来时,我需要开启一个协程把请求的一些信息记录到数据库中,但又不是很重要,所以不用管是否成功,不成功报个错就可以。但我不想这个过程影响 web 返回的时间,所以我不想 await 它完成,甚至在 web 返回后再处理这个就行,这个要怎么办。

即使 loop.run_in_executor ()也要 await。。。

来自一个中了 golang 的毒的人。

3189 次点击
所在节点    Python
10 条回复
ipwx
2019-10-15 10:08:13 +08:00
loop.create_task

但你这么做不合理
syrupofplum
2019-10-15 10:16:54 +08:00
新起一个线程,在那个线程中跑新的 event_loop,不重要的任务可以放在那个里面处理。
andylsr
2019-10-15 10:17:02 +08:00
开一个线程专门处理?
dafsic
2019-10-15 10:20:56 +08:00
@ipwx 傻了,看的例子都是 create_task,然后在 await,文档上明明写了会排期准备执行,被我忽略了。这么做有啥不合理?
ClericPy
2019-10-15 10:23:39 +08:00
同步思维里会开个线程丢到后台里跑
异步里面, 旧版本使用 asyncio.ensure_future, 新版本支持 create_task
简单的说就是一个协程函数 -> Task 的过程, 就是让它去执行的过程, 不变 Task 就不会执行, Task 和协程都可以被 await

至于上面说的那些个起一个线程的是什么鬼我也不知道, 但是线程有个好处就是有个 daemon 参数, 这个参数控制的是主线程在运行完毕后是否等待这个在跑的子线程跑完再退出程序. asyncio 的 Task 有没有这功能不太确定, 一般情况下会被直接 cancel 丢弃
dafsic
2019-10-15 10:26:42 +08:00
开一个新线程没多大用吧,开就开一个进程,这样才能利用多核,loop.run_in_executor ()这个就可以开一个新的进程,运行 cpu 阻塞函数。我主要卡在 await 这个了,以为都要 await。
dafsic
2019-10-15 10:29:39 +08:00
@ClericPy 明白,我主线程永不退出,除非关机。
ClericPy
2019-10-15 10:35:46 +08:00
@dafsic 我也是这个场景下用的, 不过一般会带 timeout 跑, 超时 cancel
理解协程比较粗糙的想法就是
协程函数 ->

协程(相当于一个迭代器但是没开始迭代) + Future (相当于一个 awaitable 的对象, 在 set_result 的时候标记状态为 done, 结束 await, 很多语言里有这种 Future 概念) ->

组成一个 Task(Task 是 Future 子类) ->

Task 里如果没指定 Loop, 会在 get_event_loop 得到的那个里面开始执行, 主要注意两个问题, 1 不能在 difference Loop 执行的报错 2. Loop 已经 running ->
Task 可以被 wait, 这里可以设置超时; 也可以被 await, 也有办法设置超时, 阻塞该行代码, 不阻塞主线程; 要注意有的 timeout 会 cancel, 有的不会;

协程对线程最优良的一个地方就是, 随时可以中断, 线程想中断太难了
ipwx
2019-10-15 14:44:01 +08:00
我是说立刻返回结果给用户不合理。

因为这样可能导致大量用户得到了正反馈,然而你其实一个都没执行完。。。
Harlaus
2019-10-22 10:23:03 +08:00
其实你要的是异步定时任务罢了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/609386

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX