最近在看 async/await 模型的协程,貌似 async 必须 await..
Golang 首先不用 await 一个 courotine,其次可以 select+channel...
你们可以教教我怎么 async+await 实现并发协程么?
1
wellsc 2018-01-17 17:24:06 +08:00
两者其实不是一个层级的东西,asyncio 只是暴露了协程的 Python 接口供开发者使用,充其量就是加了点语法糖。Golang 则是建立在 CSP model 上来调度协程,底层已经封装了很多东西了。
|
2
owenliang OP @wellsc 我理解目前 asyncio 能做的就是把常用的 tcp server 重度封装一下,把 accept 阶段扇出 coroutine 的事情帮用户做了,剩下的基本靠用户自己基于 event driven loop+generator 再封装的样子。
|
4
owenliang OP @wellsc event driven 本身是并发的,结果语法糖到 await,async 上变成了串行的,附赠了一个 wait_all 之类的糖说可以并发,感觉略扯。
|
5
chenqh 2018-01-17 17:31:30 +08:00
你把 golang 的协程当成别一种线程就容易理解了
|
6
owenliang OP 很多年前造过 C+lua 协程的网络框架,实际上也是在 C 层把常用的 server 和 read/write api 都封装好了,直接给 connection 协程用,所以当时并没有觉得这种协程模型难受。
链接: http://bbs.chinaunix.net/thread-4076795-1-1.html 但是我觉得在一个提倡简单的脚本语言里搞这种半成品,实在是费解。 |
7
qsnow6 2018-01-17 17:41:05 +08:00
暂时没好的解决方案,将个烂就
|
8
owenliang OP 照我看,asyncio 里的 loop 可能比较有用,其他的语法就算了 -,-#
|
9
owenliang OP 竟然有 goless 这种库,配合 gevent 模拟 go 的 csp 模型
|
10
est 2018-01-17 19:54:15 +08:00
继续 gevent 走起。
|
11
Contextualist 2018-01-17 19:56:35 +08:00 via iPad
说到 goless 我就想起了 offset ( https://github.com/benoitc/offset ),这个还重写了异步版标准库,可惜基于 fiber,有些弱。不过这俩库的作者貌似都弃坑了…… 之前我都玩过一下,好像效果跟 golang 的还是有些差异
|
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/ |
13
loading 2018-01-17 20:05:23 +08:00 via Android
go func 就我这种菜鸟都会用了。
|
14
owenliang OP @Contextualist 老玩家,难道你已经看透
|
15
owenliang OP @chengzhoukun 了解一下
|
16
clino 2018-01-17 20:21:05 +08:00
gevent +1
|
17
missdeer 2018-01-17 20:40:34 +08:00
@owenliang 一直有个问题想不明白,Lua 的 coroutine 是协作调度的,也就是说当前执行的 coroutine 自己主动 yield 出去,其他 coroutine 才有机会执行。那如果当 coroutine 遇到了会 block 的操作时,怎么 yield 出去,什么时候 yield ?不然不在被 block 时 yield 出去,怎么做到多个 coroutine 并发的效果呢?
|
18
owenliang OP @missdeer lua 实际上是为 c 服务的,主体在 c。lua 有协程能力,简单说就是保存上下文暂停执行( yield ),让你感觉同步写逻辑。c 有事件驱动能力,为 lua api 提供异步能力。所以 c 基本是做服务框架和 lua api 的异步逻辑,而 lua 做 api 的壳以及切换到 c 异步事件之前的 yield 调用。
|
20
owenliang OP gevent 我还需要再看看特性,有类线程和队列,但没有多路。
|
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 的语法糖强多了 |
22
wwqgtxx 2018-01-17 21:04:32 +08:00 via iPhone
@owenliang gevent 是有多路的,通过 libev 实现了对 socket api 的多路复用
|
24
doubleflower 2018-01-17 23:31:41 +08:00 via Android
python 这个 asyncio 第一天粗看了一遍文档看得云里雾里,还好晚上想了一.晚想通了,不如像 js 这样简单化处理
|
25
Earthson 2020-02-21 16:47:13 +08:00
有像 join 的 asyncio.gather,还有一个类似 select 的 asyncio.wait,要是没啥依赖,直接丢 asyncio.create_task
|