如何让 asyncio 按照优先级顺序来执行执行几个有优先级的可等待对象? - V2EX
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
abersheeran
V2EX    Python

如何让 asyncio 按照优先级顺序来执行执行几个有优先级的可等待对象?

  •  
  •   abersheeran 2020-12-09 15:17:40 +08:00 3019 次点击
    这是一个创建于 1842 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设事件循环里有一百万个可等待对象,其中一万个可以继续进行了,其他的仍然在等待。那么如何让这一万对象按照优先级顺序顺序执行?

    我猜测要从 asyncio 源码下手,有没有读过源码的大佬给个大概的可入手的地方,比如事件循环是在哪里遍历对象判断可执行的?或者有现成的仓库?(谷歌、必应、百度过,没搜到,所以我猜大概率没有,就算有,也是藏得很深的)

    19 条回复    2021-07-21 19:12:19 +08:00
    wellsc
        1
    wellsc  
       2020-12-09 15:19:55 +08:00
    abersheeran
        2
    abersheeran  
    OP
       2020-12-09 15:24:58 +08:00
    @wellsc 我想问的是优先级,而不是命名。
    ruanimal
        3
    ruanimal  
       2020-12-09 15:29:51 +08:00
    @abersheeran 把任务放优先队列里就行了
    BBrother
        4
    BBrother  
       2020-12-09 15:32:00 +08:00
    可不可以全局维护一个优先级表,每个 task 执行前先查询优先级,如果不是最高的,就再把自己加入到事件循环中?
    geebos
        5
    geebos  
    PRO
       2020-12-09 15:34:29 +08:00
    自定义一个 eventloop,在 task 类上添加一个优先级,在 select 的时候把准备好的任务添加到优先队列里再执行,但是感觉性能不太好。我建议分几个优先级,不同优先级有执行顺序,相同优先级的按到达顺序执行,这样在选取的时候遍历一遍就可以。
    wellsc
        6
    wellsc  
       2020-12-09 15:40:31 +08:00 via iPhone
    @abersheeran 按照命名排序不就好了
    abersheeran
        7
    abersheeran  
    OP
       2020-12-09 16:08:24 +08:00
    不回复以上回复,是因为我不想开口骂人。

    有没有真正 hack 过 asyncio 事件循环的大佬能给点具体的建议?
    BBCCBB
        8
    BBCCBB  
       2020-12-09 16:27:38 +08:00
    每个对象加一个 condition?
    然后后一个对象等待前一个对象的 condition signal. 看看这样可不可行
    BBCCBB
        9
    BBCCBB  
       2020-12-09 16:28:28 +08:00
    或者楼上说的放优先队列里一个一个拿出来跑也没问题呀.
    abersheeran
        10
    abersheeran  
    OP
       2020-12-09 16:45:20 +08:00
    @BBCCBB 问题里我觉得我问的很明确了,我想要的是具体的入手点或者现有的库,而不是思路。优先级队列这种入门级的思路,我也能想到啊,关键是这个队列放在哪?在哪里把元素放进去?事件循环里哪个 API 可以用来 hack 这种操作?我想要的是这些。
    BBCCBB
        11
    BBCCBB  
       2020-12-09 16:58:56 +08:00
    当我没说.

    假设事件循环里有一百万个可等待对象,其中一万个可以继续进行了,其他的仍然在等待。那么如何让这一万对象按照优先级顺序顺序执行?

    大家回答的你第一个问题.
    0qeIrKoJk345hkoo
        12
    0qeIrKoJk345hkoo  
       2020-12-09 16:59:21 +08:00
    不想骂人可还行,在论坛发了这个帖子这个帖子就是你家了?别人不能进来谈一下看法?你只是发起了一个讨论,你没有拥有这个帖子,你也没资格指责别人怎么不如你意了
    abersheeran
        13
    abersheeran  
    OP
       2020-12-09 17:10:47 +08:00
    @BBCCBB ……好的,下次我尽量让问题重点更显眼一些。

    @hgrx 你当然有发评论的权力,我同样有反驳你发的评论的权力,包括对你们评论的批评和猛烈批评,我只是用了一个口语化的形容“骂”。怎么?只讲你们的权力,我就是没人权的人了?
    lyzh
        14
    lyzh  
       2020-12-09 17:31:00 +08:00
    @hgrx 所以他没开口骂人你都觉得不爽,那我来阴阳你一下你你开心咯?
    se77en
        15
    se77en  
       2020-12-09 20:23:16 +08:00
    asyncio.wait 有个 return_when 参数,可以参考一下这个 https://stackoverflow.com/a/48567863/2050626
    abersheeran
        16
    abersheeran  
    OP
       2020-12-09 22:29:00 +08:00
    @se77en 谢谢,这个我也搜到了。不过它这个并没有真的实现一个按照优先级执行的事件循环。

    这个问题我打算给它沉掉,有一个看过源码的大佬说这个搞不定,没有对应的 API 。符合我最开始的推断,只能像 trio 一样重写一套,成本太高了。唉。不过还是谢谢你花时间帮我搜答案。
    linw1995
        17
    linw1995  
       2020-12-10 11:27:55 +08:00   2
    1. 让各个 asyncio.Task 带上优先级
    可以通过 loop.set_task_factory 让各个 coroutins 有优先级,可以不修改 Task 对象,优先级存在 context 里就好了。这样其产生的新 task 可以继承这个优先级

    2. 修改 loop._run_once 使其按优先级执行(不行)
    _run_once 是在跑一个个 callbacks,所以没法用来使 asyncio.Task 按优先级执行

    所以就只能在 asyncio.Task.__step 这里搞幺蛾子了,维持一个全局的优先级堆,执行 __step 先检查一下自己的优先级在不在堆顶,看该不该继续执行,不该就重新 call_soon 。

    按这个思路应该可以搞起来
    abersheeran
        18
    abersheeran  
    OP
       2020-12-10 12:05:09 +08:00
    @linw1995 这样就是在 asyncio 里,手动创建一个由 Task 作为基本单位的带优先级的事件循环。看起来可行!感谢!

    这个思路我是真没想到,不需要去走 loop 的接口,只要调整 Task,保证每个可等待对象都被 Task 包装起来就行了。太有意思了。是我之前的想法钻牛角尖了
    joApioVVx4M4X6Rf
        19
    joApioVVx4M4X6Rf  
       2021-07-21 19:12:19 +08:00
    请问后来解决了吗?怎么解决的?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3611 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 00:04 PVG 08:04 LAX 16:04 JFK 19:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86