@
leeg810312 比如我要写一个 redis client ,需要用同步 IO 的 API 和异步 IO 的 API 分别实现一遍,代码逻辑完全一样,为什么不能只写一遍?除了底层语言没有必要同步异步都有,像 go 、erlang 可以全都是异步,异步不增加任何额外的复杂度和学习成本。green thread 也没有这个问题。
至于真正需要全都有的,可以了解一下 zig 的 color blind async ,只需要实现一遍,同步 context 下 async 自动变成 noop 。
异步 context 调用同步方法导致阻塞就是 async/await 模型的缺陷。你要说是实现的问题,你到说说哪个 async/await 的实现可以调用同步方法而不阻塞?
贴里讨论的一直都是 programming pattern ,根本没有提到过 scheduler/runtime 具体实现的问题,上面讨论的也是 task 具有 structural 的特性(await task will resume after all sub task awaited finished)从而可以更细粒度的控制不同的 task 由不同的 executor (单线程 /多线程)执行。这确实是 async/await 比 goroutine 的优点,但如果 green thread 引入了 structural concurrency 也是一样可以实现的。
async/await 在过去一段时间确实非常流行,但没有任何范式可以适用于所有的需求,没有银弹,自然没有哪个能成为是“最好”。
何况 async/await 有很多问题和批评, 如
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ ,hn 上每几个月都上一次头条,没看过可以看一下。
建议多了解一些不同的语言和范式,C#是一门优秀的语言,但它也有历史的局限性。很多当时的设计但若干年后发现有问题的(比如 void 不能作为泛型参数)。erlang/elixir 可以写出天然分布式的程序,actor model 广泛在 OOP 中使用,green thread 极大的简化了异步 IO 的复杂度,直接编写同步代码并获得异步 IO 的并发性能提升 nearly for free 。structural concurrency 是 trio 的作者提出的,要求任何函数 spawn 的 task 必须在函数返回前结束,希望像现代编程语言的控制流取代 goto 一样取代当前 spawn 的 task 可以自由运行 for any time ,详细阅读
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/go 里的 errgroup 和 rust 的 scoped_thread 都是该范式的体现,并且被 kotlin 作为了官方的协程范式。