用 aiohttp 框架,当一个 web 请求过来时,我需要开启一个协程把请求的一些信息记录到数据库中,但又不是很重要,所以不用管是否成功,不成功报个错就可以。但我不想这个过程影响 web 返回的时间,所以我不想 await 它完成,甚至在 web 返回后再处理这个就行,这个要怎么办。
即使 loop.run_in_executor ()也要 await。。。
来自一个中了 golang 的毒的人。
1
ipwx 2019-10-15 10:08:13 +08:00 via Android 1
loop.create_task
但你这么做不合理 |
2
syrupofplum 2019-10-15 10:16:54 +08:00
新起一个线程,在那个线程中跑新的 event_loop,不重要的任务可以放在那个里面处理。
|
3
andylsr 2019-10-15 10:17:02 +08:00 via Android
开一个线程专门处理?
|
4
dafsic OP @ipwx 傻了,看的例子都是 create_task,然后在 await,文档上明明写了会排期准备执行,被我忽略了。这么做有啥不合理?
|
5
ClericPy 2019-10-15 10:23:39 +08:00 1
同步思维里会开个线程丢到后台里跑
异步里面, 旧版本使用 asyncio.ensure_future, 新版本支持 create_task 简单的说就是一个协程函数 -> Task 的过程, 就是让它去执行的过程, 不变 Task 就不会执行, Task 和协程都可以被 await 至于上面说的那些个起一个线程的是什么鬼我也不知道, 但是线程有个好处就是有个 daemon 参数, 这个参数控制的是主线程在运行完毕后是否等待这个在跑的子线程跑完再退出程序. asyncio 的 Task 有没有这功能不太确定, 一般情况下会被直接 cancel 丢弃 |
6
dafsic OP 开一个新线程没多大用吧,开就开一个进程,这样才能利用多核,loop.run_in_executor ()这个就可以开一个新的进程,运行 cpu 阻塞函数。我主要卡在 await 这个了,以为都要 await。
|
8
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, 有的不会; 协程对线程最优良的一个地方就是, 随时可以中断, 线程想中断太难了 |
9
ipwx 2019-10-15 14:44:01 +08:00
我是说立刻返回结果给用户不合理。
因为这样可能导致大量用户得到了正反馈,然而你其实一个都没执行完。。。 |
10
Harlaus 2019-10-22 10:23:03 +08:00
其实你要的是异步定时任务罢了
|