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
owenliang
V2EX  ›  Python

async/await 和 golang 协程,好像不在一个易用性程度上。

  •  
  •   owenliang ·
    owenliang · 2018-01-17 17:15:47 +08:00 · 9568 次点击
    这是一个创建于 2502 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在看 async/await 模型的协程,貌似 async 必须 await..

    Golang 首先不用 await 一个 courotine,其次可以 select+channel...

    你们可以教教我怎么 async+await 实现并发协程么?

    25 条回复    2020-02-21 16:47:13 +08:00
    wellsc
        1
    wellsc  
       2018-01-17 17:24:06 +08:00
    两者其实不是一个层级的东西,asyncio 只是暴露了协程的 Python 接口供开发者使用,充其量就是加了点语法糖。Golang 则是建立在 CSP model 上来调度协程,底层已经封装了很多东西了。
    owenliang
        2
    owenliang  
    OP
       2018-01-17 17:26:53 +08:00
    @wellsc 我理解目前 asyncio 能做的就是把常用的 tcp server 重度封装一下,把 accept 阶段扇出 coroutine 的事情帮用户做了,剩下的基本靠用户自己基于 event driven loop+generator 再封装的样子。
    wellsc
        3
    wellsc  
       2018-01-17 17:29:13 +08:00
    @owenliang #2 asyncio 是操作系统层面的协程接口,csp 是并发模型
    owenliang
        4
    owenliang  
    OP
       2018-01-17 17:30:56 +08:00
    @wellsc event driven 本身是并发的,结果语法糖到 await,async 上变成了串行的,附赠了一个 wait_all 之类的糖说可以并发,感觉略扯。
    chenqh
        5
    chenqh  
       2018-01-17 17:31:30 +08:00
    你把 golang 的协程当成别一种线程就容易理解了
    owenliang
        6
    owenliang  
    OP
       2018-01-17 17:36:19 +08:00
    很多年前造过 C+lua 协程的网络框架,实际上也是在 C 层把常用的 server 和 read/write api 都封装好了,直接给 connection 协程用,所以当时并没有觉得这种协程模型难受。

    链接: http://bbs.chinaunix.net/thread-4076795-1-1.html

    但是我觉得在一个提倡简单的脚本语言里搞这种半成品,实在是费解。
    qsnow6
        7
    qsnow6  
       2018-01-17 17:41:05 +08:00
    暂时没好的解决方案,将个烂就
    owenliang
        8
    owenliang  
    OP
       2018-01-17 17:42:35 +08:00
    照我看,asyncio 里的 loop 可能比较有用,其他的语法就算了 -,-#
    owenliang
        9
    owenliang  
    OP
       2018-01-17 19:39:42 +08:00 via Android
    竟然有 goless 这种库,配合 gevent 模拟 go 的 csp 模型
    est
        10
    est  
       2018-01-17 19:54:15 +08:00
    继续 gevent 走起。
    Contextualist
        11
    Contextualist  
       2018-01-17 19:56:35 +08:00 via iPad
    说到 goless 我就想起了 offset ( https://github.com/benoitc/offset ),这个还重写了异步版标准库,可惜基于 fiber,有些弱。不过这俩库的作者貌似都弃坑了…… 之前我都玩过一下,好像效果跟 golang 的还是有些差异
    chengzhoukun
        12
    chengzhoukun  
       2018-01-17 20:00:28 +08:00
    async/await 是 C#最先用的吧,然后是 Python,JS,
    不过 python 里面搞的确实复杂了,flask 作者就写过一篇文章:
    http://lucumr.pocoo.org/2016/10/30/i-dont-understand-asyncio/
    loading
        13
    loading  
       2018-01-17 20:05:23 +08:00 via Android
    go func 就我这种菜鸟都会用了。
    owenliang
        14
    owenliang  
    OP
       2018-01-17 20:08:58 +08:00 via Android
    @Contextualist 老玩家,难道你已经看透
    owenliang
        15
    owenliang  
    OP
       2018-01-17 20:09:15 +08:00 via Android
    @chengzhoukun 了解一下
    clino
        16
    clino  
       2018-01-17 20:21:05 +08:00
    gevent +1
    missdeer
        17
    missdeer  
       2018-01-17 20:40:34 +08:00
    @owenliang 一直有个问题想不明白,Lua 的 coroutine 是协作调度的,也就是说当前执行的 coroutine 自己主动 yield 出去,其他 coroutine 才有机会执行。那如果当 coroutine 遇到了会 block 的操作时,怎么 yield 出去,什么时候 yield ?不然不在被 block 时 yield 出去,怎么做到多个 coroutine 并发的效果呢?
    owenliang
        18
    owenliang  
    OP
       2018-01-17 20:50:28 +08:00 via Android
    @missdeer lua 实际上是为 c 服务的,主体在 c。lua 有协程能力,简单说就是保存上下文暂停执行( yield ),让你感觉同步写逻辑。c 有事件驱动能力,为 lua api 提供异步能力。所以 c 基本是做服务框架和 lua api 的异步逻辑,而 lua 做 api 的壳以及切换到 c 异步事件之前的 yield 调用。
    owenliang
        19
    owenliang  
    OP
       2018-01-17 20:51:24 +08:00 via Android
    @owenliang 补充一下,c 在事件完成后 resume lua 的协程。
    owenliang
        20
    owenliang  
    OP
       2018-01-17 20:55:28 +08:00 via Android
    gevent 我还需要再看看特性,有类线程和队列,但没有多路。
    wwqgtxx
        21
    wwqgtxx  
       2018-01-17 21:02:11 +08:00 via iPhone
    说到底 py3 的 async/await 本质上只是生成器和迭代器的语法糖,而 golang 的 go func 是语言级别的并发模型,两者自然没有可比性
    python 标准库中大部分的 api 都是阻塞式的,不可能为了支持协程而大范围修改系统库(为了兼容性),虽然 gevent 的 monkey patch 可以实现把整个系统的线程都改成协程操作的,不过如果调用了 c 库就会阻塞整个程序(需要自己对 gevent.ThreadPool 进行封装调用)
    而 golang 的 runtime 在底层就是实现了 n 对 m 的线程+协程模型,当然比 py3 的语法糖强多了
    wwqgtxx
        22
    wwqgtxx  
       2018-01-17 21:04:32 +08:00 via iPhone
    @owenliang gevent 是有多路的,通过 libev 实现了对 socket api 的多路复用
    owenliang
        23
    owenliang  
    OP
       2018-01-17 21:41:19 +08:00 via Android
    @wwqgtxx 我是指 select 多路 channel
    doubleflower
        24
    doubleflower  
       2018-01-17 23:31:41 +08:00 via Android
    python 这个 asyncio 第一天粗看了一遍文档看得云里雾里,还好晚上想了一.晚想通了,不如像 js 这样简单化处理
    Earthson
        25
    Earthson  
       2020-02-21 16:47:13 +08:00
    有像 join 的 asyncio.gather,还有一个类似 select 的 asyncio.wait,要是没啥依赖,直接丢 asyncio.create_task
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2820 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:30 · PVG 21:30 · LAX 05:30 · JFK 08:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.