跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • c++ 有没有能够对标 golang 的 goroutine 的协程库啊?
未分類
29 10 月 2020

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

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

資深大佬 : Yc1992 1

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

大佬有話說 (43)

  • 資深大佬 : keygen88

    协程库很多,但很多其它库不支持就比较鸡肋了,这就是个生态问题。

  • 資深大佬 : reus

    goroutine 本来就不是协程,对标的就是线程

  • 資深大佬 : ysc3839

    自动 yield 大概要能插入代码吧? C++ 大概没有这种能力。
    而且 C++20 的 stackless coroutine 出来之后,stackful 的可能会越来越少了。

  • 資深大佬 : abbycin

    libgo 看过没?

  • 主 資深大佬 : Yc1992

    @abbycin 谢谢,正在看

  • 主 資深大佬 : Yc1992

    @ysc3839 为什么 stackless 更多呢?

  • 資深大佬 : ysc3839

    @Yc1992 因为人们会更倾向于使用语言本身的功能吧?

  • 主 資深大佬 : Yc1992

    @reus 第一次听到这样的描述

  • 資深大佬 : nightwitch

    https://en.cppreference.com/w/cpp/language/coroutines
    一大波库正在路上

  • 資深大佬 : zunceng

    早几年用 asio coro 玩过
    不过那个上面的 yield 就是对 for loop … switch case 做了个封装 用起来还是太费脑

  • 主 資深大佬 : Yc1992

    @nightwitch 补充一下,必须 c++11 哈

  • 資深大佬 : nannanziyu

    @Yc1992
    限定 c++11 的话,微软的 cpprestsdk 里有一个 pplx

  • 資深大佬 : catror

    用 asio+fiber 写过一个网络程序框架,用着也还行吧

  • 資深大佬 : CRVV

    @Yc1992
    如果你去看 Go 的官方文档,里面明确说了这东西不是 coroutine,当然它也不是 thread,所以才起了个新名字叫 goroutine

    大家常说它是协程,是因为它和协程很像,在 io 上也用 epoll, kqueue, iocp 这些系统调用,并且它也确实在 io 操作上 yield 了,老版本上的调度器还不是抢占式的。

    但首先新的调试器已经是抢占式的了,这就不符合协程的定义。然后你对比一下实现的细节,显然现在的 goroutine 和 thread 更接近。

    别人怎么说并不重要,你得去看实际的东西。

  • 主 資深大佬 : Yc1992

    @CRVV 不同的调度方式而已,https://golang.org/doc/faq#goroutines 里面明确提到了 coroutine

  • 資深大佬 : reus

    @Yc1992 协程当然是协作式调度,但 goroutine 并不限制调度方式,现在的实现就是有抢占式的调度方式,跑着死循环的 goroutine 也可以被抢占,所以 goroutine 并不是协程。
    FAQ 那段话是 11 年前写的: https://github.com/golang/go/commit/d4a4468204448843d0dd15d2d4b89c29607a4a7e
    那时候的 goroutine 确实是协作式调度,没有任何抢占机制。但现在 goroutine 已经不是 11 年前那样了,FAQ 那段话是过时的了。不会有任何协程实现可以有 goroutine 这样的性质,就算可以自动调度,也做不到抢占式调度。只有线程具有抢占式调度的特性,所以说 goroutine 对标线程。

  • 資深大佬 : zzzbkl

    试试 boost fiber

  • 主 資深大佬 : Yc1992

    @zzzbkl 看了半天,不会用,貌似要手动 yield

  • 資深大佬 : hdbzsgm

    folly

  • 資深大佬 : wnpllrzodiac

    st?

  • 資深大佬 : sujin190

    @reus #16 你确定? go13 的时候写个死循环照样卡死其他 goroutine 啊,啥时候改了抢占式了

  • 資深大佬 : caviar

    @sujin190 go1.14 的时候开始的 https://golang.org/doc/go1.14#runtime

  • 資深大佬 : user8341

    @caviar 这个很新,可能很多人还没用上

    Go 1.14 发布日期是:25 February 2020

  • 資深大佬 : BadMan

    我在使用微信的 libco,挺好用的

  • 資深大佬 : hronro

    居然这么多人说 Go 的 goroutine 不是协程,还有说可以抢占的就不是协程。
    难道不是 stackful coroutine 都可以做到抢占吗? stackless coroutine 确实做不了抢占。

  • 資深大佬 : framlog

    seastar

  • 資深大佬 : beidounanxizi

    @reus 调度方式最新版本确实变了 尤其是 1.10 之后 ,但是 GMP 这一整套逻辑 是不是还是说和其他 coroutine 的差不多呢? 疑问脸.jpg

  • 資深大佬 : reus

    @sujin190 1.14

  • 資深大佬 : reus

    @beidounanxizi 和哪个协程实现差不多?请举出例子,不要相当然。

  • 資深大佬 : hankai17

    swapcontext

  • 資深大佬 : reus

    另外就普适性而言,和 goroutine 对等的,也是线程。在 go 里,你只能用 goroutine,不存在其他并发单元。而 C/C++
    里,能担当这个任务的,只能是 pthread 这类线程库,而不是其他协程库,因为协程库还没有统一的标准,你用这个,他用那个,没法融合的。
    另外,虽然现在主流 pthread 实现,都是 1:1 映射到系统线程,但是,M:N 映射到系统线程的 pthread 实现,也是存在的。pthread 线程,和 goroutine,都只是并发的单元,具体怎么实现,对于使用者是不可见的。goroutine 历史上曾经实现为纯协作式调度,不代表它就是协程。因为它加入抢占式调度之后,程序也不需要变化,怎么调度都不影响语义,这是协程不具备的性质。协程语义一般都会有确定的调度点,例如 yield 语句、await 语句,而不会是任何地方。

  • 資深大佬 : Balthild

    @reus 从普遍意义上讲,「抢占即非协程」似乎不那么绝对。比如,Rust 有抢占式的异步运行时实现,比如 tokio 、smol 等。若按「抢占即非协程」定律,Rust 的异步就不是协程了。但 Rust 异步的设计明确自己是 stackless coroutine 。这需要如何解释呢?

  • 資深大佬 : missdeer

    赞同 31 。

    早些年,coroutine 概念还几乎不见于日常开发,很多操作系统(比如 DOS,一些 UNIX )还不支持内核线程时,有第三方库(比如 pthread)实现用户态线程及调度,当然后来 pthread 的实现也千变万化。

  • 資深大佬 : fpure

    @CRVV 绿色线程?

  • 資深大佬 : reus

    @Balthild tokio 并不是抢占式的运行时,tokio 文档里清晰说了的: https://tokio.rs/blog/2020-04-preemption
    你对“抢占”的理解有误。

  • 資深大佬 : reus

    @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

    @Balthild
    @hronro

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

    这是这个 coroutine 原本的意思。

    在一个 stackful coroutine 的实现上加上抢占式调度,那当然可以做。
    但做出来的东西就不叫 coroutine 了。

  • 資深大佬 : CRVV

    @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

    @CRVV 我明白你的意思,也不用去纠结名字,总之都是对线程的一个封装

  • 資深大佬 : user8341

    各位大佬,golang 什么情况下会调用 调度器?

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

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

  • 資深大佬 : user8341

    另外,1.14 版加入了时间片,时间片用完 sysmon 会通过发送 signal 给线程的方式,强制一个 goroutine 调用 调度器。

  • 資深大佬 : dollar

    brpc 中的 bthread 挺好用的

  • 資深大佬 : joydee

    可以尝试看看 Rangev3 作者 Eric Niebler 用过的 c++ coroutine 库,链接[https://github.com/lewissbaker/cppcoro],遵从 C++ coroutines TS N4680,不过代码还是蛮晦涩的,慎用

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具