V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dafsic
V2EX  ›  Python

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

  •  
  •   dafsic · 2019-10-15 10:01:02 +08:00 · 3203 次点击
    这是一个创建于 1891 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    10 条回复    2019-10-22 10:23:03 +08:00
    ipwx
        1
    ipwx  
       2019-10-15 10:08:13 +08:00 via Android   ❤️ 1
    loop.create_task

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

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

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

    因为这样可能导致大量用户得到了正反馈,然而你其实一个都没执行完。。。
    Harlaus
        10
    Harlaus  
       2019-10-22 10:23:03 +08:00
    其实你要的是异步定时任务罢了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5632 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 06:34 · PVG 14:34 · LAX 22:34 · JFK 01:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.