c++ 有没有能够对标 golang 的 goroutine 的协程库啊?

2020-10-28 11:48:56 +08:00
 Yc1992

满足 stackful,能够自动 yield 的,有没有? 看了好几个都需要手动 yield 归还 cpu,感觉有点麻烦,希望大佬指点下,不奢求同时有 channel 和 select 了

6857 次点击
所在节点    C++
44 条回复
sujin190
2020-10-28 18:35:54 +08:00
@reus #16 你确定? go13 的时候写个死循环照样卡死其他 goroutine 啊,啥时候改了抢占式了
caviar
2020-10-28 18:50:35 +08:00
user8341
2020-10-28 18:57:51 +08:00
@caviar 这个很新,可能很多人还没用上

Go 1.14 发布日期是:25 February 2020
BadMan
2020-10-28 19:17:46 +08:00
我在使用微信的 libco,挺好用的
hronro
2020-10-28 19:47:13 +08:00
居然这么多人说 Go 的 goroutine 不是协程,还有说可以抢占的就不是协程。
难道不是 stackful coroutine 都可以做到抢占吗? stackless coroutine 确实做不了抢占。
framlog
2020-10-28 19:58:06 +08:00
seastar
beidounanxizi
2020-10-28 20:18:40 +08:00
@reus 调度方式最新版本确实变了 尤其是 1.10 之后 ,但是 GMP 这一整套逻辑 是不是还是说和其他 coroutine 的差不多呢? 疑问脸.jpg
reus
2020-10-28 20:29:58 +08:00
@sujin190 1.14
reus
2020-10-28 20:45:34 +08:00
@beidounanxizi 和哪个协程实现差不多?请举出例子,不要相当然。
hankai17
2020-10-29 00:00:41 +08:00
swapcontext
reus
2020-10-29 01:03:44 +08:00
另外就普适性而言,和 goroutine 对等的,也是线程。在 go 里,你只能用 goroutine,不存在其他并发单元。而 C/C++
里,能担当这个任务的,只能是 pthread 这类线程库,而不是其他协程库,因为协程库还没有统一的标准,你用这个,他用那个,没法融合的。
另外,虽然现在主流 pthread 实现,都是 1:1 映射到系统线程,但是,M:N 映射到系统线程的 pthread 实现,也是存在的。pthread 线程,和 goroutine,都只是并发的单元,具体怎么实现,对于使用者是不可见的。goroutine 历史上曾经实现为纯协作式调度,不代表它就是协程。因为它加入抢占式调度之后,程序也不需要变化,怎么调度都不影响语义,这是协程不具备的性质。协程语义一般都会有确定的调度点,例如 yield 语句、await 语句,而不会是任何地方。
Balthild
2020-10-29 04:04:12 +08:00
@reus 从普遍意义上讲,「抢占即非协程」似乎不那么绝对。比如,Rust 有抢占式的异步运行时实现,比如 tokio 、smol 等。若按「抢占即非协程」定律,Rust 的异步就不是协程了。但 Rust 异步的设计明确自己是 stackless coroutine 。这需要如何解释呢?
missdeer
2020-10-29 08:52:55 +08:00
赞同 31 楼。

早些年,coroutine 概念还几乎不见于日常开发,很多操作系统(比如 DOS,一些 UNIX )还不支持内核线程时,有第三方库(比如 pthread)实现用户态线程及调度,当然后来 pthread 的实现也千变万化。
fpure
2020-10-29 09:04:19 +08:00
@CRVV 绿色线程?
reus
2020-10-29 09:21:55 +08:00
@Balthild tokio 并不是抢占式的运行时,tokio 文档里清晰说了的: https://tokio.rs/blog/2020-04-preemption
你对“抢占”的理解有误。
reus
2020-10-29 09:28:02 +08:00
@Balthild 划出 tokio 文档里的重点给你:
A common solution to this problem is preemption. With normal OS threads, the kernel will interrupt execution every so often in order to ensure fair scheduling of all threads.
os 线程支持抢占
Runtimes that have full control over execution (Go, Erlang, etc.) will also use preemption to ensure fair scheduling of tasks.
go 、erlang 也支持抢占
This is accomplished by injecting yield points — code which checks if the task has been executing for long enough and yields back to the scheduler if so — at compile-time.
插入调度点,这是 go 过去的做法,现在增加了用信号去抢占的方式
Unfortunately, Tokio is not able to use this technique as Rust's async generators do not provide any mechanism for executors (like Tokio) to inject such yield points.
tokio 不支持抢占

你的大前提错了,推论自然全错。
CRVV
2020-10-29 10:20:28 +08:00
@Balthild
@hronro

https://en.wikipedia.org/wiki/Coroutine#Comparison_with_threads
协程,coroutine,co 是 cooperatively,合作协作的意思。
相对的概念是 preemptively,抢占

这是这个 coroutine 原本的意思。

在一个 stackful coroutine 的实现上加上抢占式调度,那当然可以做。
但做出来的东西就不叫 coroutine 了。
CRVV
2020-10-29 10:53:49 +08:00
@Yc1992
我本来想说的就是这一段。

When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.

这里说的不是把多个 coroutine 放到同一个线程上来跑。是说如果有一个 coroutine 阻塞住了一个 thread,就把其它的 coroutine 放到别的线程上跑。

然后有一句话,The programmer sees none of this, which is the point. The result, which we call goroutines, ...

所以总结一下就是,有一个协程,它 block 住了(比如在 python 的 async function 里面写了一句 time.sleep ),这样其它的协程就不能跑了对吧,那我们写一个高级一点的 runtime,把能跑的协程放到其它 thread 上跑。
并且把这些过程都隐藏起来,什么 yield 之类的东西都没有了,都是 runtime 里面的事情。

所以说这是一个基于 coroutine 的想法,或者说是一个经过了大改的 coroutine,还专门说了这个东西叫 goroutine 不叫 coroutine 了。

所以还是上一条回复里面说的,它改完了就不是 coroutine 了。
Yc1992
2020-10-29 11:14:29 +08:00
@CRVV 我明白你的意思,也不用去纠结名字,总之都是对线程的一个封装
user8341
2020-10-29 11:29:04 +08:00
各位大佬,golang 什么情况下会调用 调度器?

我知道的有以下这 3 个:
1. syscall
2. go 语句
3. 阻塞读写 chan

普通函数调用会不会调用 调度器?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/719365

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX