• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wmwm
V2EX  ›  程序员

为什么只有 go 语言原生支持协程?

  •  1
     
  •   wmwm · Aug 10, 2023 · 8818 views
    This topic created in 1193 days ago, the information mentioned may be changed or developed.

    大部分语言的协程都是基于 epoll/select 机制,由于 epoll/select 只能处理 IO 问题,所以导致大部分语言的协程也只能处理 IO 问题

    而 go 语言的协程可以在任何情况下使用,是真正意义上的协程,底层是通过汇编指令 pop/push 保存上下文

    以上理解正确吗?

    46 replies  •  2023-08-12 18:37:30 +08:00
    nightwitch
    nightwitch
    Aug 10, 2023 via Android❤️2
    1
    把协程的实现放到库来做还是放到语言特性里只是语言设计者的偏好问题。协程和 epoll 也是正交的关系,没什么基于不基于的。
    thinkershare
    thinkershare
    Aug 10, 2023
    2
    因为协程并不是什么先进值得被其它语言吸收的好东西,纯粹是语言创建者的个人偏好。
    coderxy
    coderxy
    Aug 10, 2023❤️1
    3
    因为现在流行的几个语言里面,就属 go 诞生的最晚,其它语言有一定的历史包袱。
    DonaidTrump
    DonaidTrump
    Aug 10, 2023
    4
    Java 也原生支持了
    emSaVya
    emSaVya
    Aug 10, 2023❤️8
    5
    你可能需要重新理解协程的概念。

    另外应该是 2015 年前后 大批程序设计语言都上了 coroutine, 比如 c# js python 。什么概念时髦了就上什么。

    c++ coroutine 讨论了得有几十年了, 现在 c20 也加上了。
    duke807
    duke807
    Aug 10, 2023 via Android
    6
    各语言协程的底层都是通过汇编指令 pop/push 保存上下文
    lovelylain
    lovelylain
    Aug 10, 2023 via Android
    7
    @duke807 async/await 这种是状态机
    agagega
    agagega
    Aug 10, 2023 via iPhone❤️1
    8
    协程和用户态线程是不同的东西,只是 go 利用特殊设计在后者实现了前者的要达到的效果。Swift 的并发支持也有点异曲同工之妙
    sunny1688
    sunny1688
    Aug 10, 2023❤️2
    9
    yield 就是协程,很多语言都支持协程的,只不过没有语言层面实现调度器(运行时)
    touchmii
    touchmii
    Aug 10, 2023
    10
    就一个 runtime 的事情, 想支持啥特性都可以, 至于 go 为什么要放到语言特性中来自然是要宣传造势, 这是它最显著的特点.
    kenvix
    kenvix
    Aug 10, 2023
    11
    先问是不是,再问为什么。
    R4rvZ6agNVWr56V0
    R4rvZ6agNVWr56V0
    Aug 10, 2023
    12
    x y problem
    oldshensheep
    oldshensheep
    Aug 10, 2023
    13
    golang 的协程有两种抢占式和协作式,抢占式类似于 Java 的虚拟线程,协作式类似于 yield
    支持类似于 Golang 的抢占式的协程的语言有 Java ,其他的语言好像不怎么支持
    nuk
    nuk
    Aug 10, 2023❤️4
    14
    golang 从来都没有协程,goroutine 本质上是 M:N 的用户线程。
    官方的说法:
    A goroutine is a lightweight thread managed by the Go runtime.
    WebKit
    WebKit
    Aug 10, 2023 via Android
    15
    Kotlin 也支持
    ravenl
    ravenl
    Aug 10, 2023
    16
    go 的协程还没出啊
    https://research.swtch.com/coro
    AItsuki
    AItsuki
    Aug 10, 2023❤️4
    17
    goroutine 确实不是协程。协程最关键的一点是非抢占式调度,可以显式的挂起和恢复,而不是阻塞。
    ikas
    ikas
    Aug 10, 2023
    18
    不正确
    WaldenHorizon
    WaldenHorizon
    Aug 11, 2023
    19
    不懂,但 goroutine+channel 做 IO 并发真的超爽
    lightjiao
    lightjiao
    Aug 11, 2023 via iPhone❤️1
    20
    yulon
    yulon
    Aug 11, 2023
    21
    你完全说反了,Go 的底层就是 Epoll/IOCP/Kqueue ,你就算不使用网络功能,它默认就是用的 net poll ,因为它就是发明来解决网络问题的语言😅
    holulu
    holulu
    Aug 11, 2023
    22
    Go 诞生的目的是为了提升编写多核及网络应用的效率,其特性的设计肯定就围绕这个目标的。
    hankai17
    hankai17
    Aug 11, 2023
    23
    我认为 任何语言都可以实现自己的协程
    但是很少有像 go 那样 自带协程调度器
    还有我认为 抢占/非抢占 区别就是主动/非主动的'yeild'当前上下文 对于协程实现来说 不是特别难
    所以我认为 原生支持协程 原生就意味着 有协程调度器
    lysS
    lysS
    Aug 11, 2023
    24
    go 的调度就是依赖系统的异步模型啊,这样可以在 go 里面用同步代码写异步逻辑,而不用一堆回调;像文件 io 没有异步模型,go runtime 只有锁定 M
    GeminiPro
    GeminiPro
    Aug 11, 2023❤️1
    25
    只有 go 自带调度器了
    weishao2011
    weishao2011
    Aug 11, 2023
    26
    1 、epoll/select:确实,很多基于协程的异步 I/O 库利用了 epoll (在 Linux 上)或 select 来进行非阻塞 I/O 操作,以支持高并发。这些机制主要处理 I/O 问题,如网络通信、文件读写等。

    2 、大部分语言的协程只能处理 IO 问题:这不完全正确。协程的本质是一种轻量级的线程抽象,用于支持高效地切换执行上下文。而是否主要用于 I/O 取决于其使用场景和设计目的。有些系统和库的确重点强调了 I/O ,但协程本身的设计和实现并不局限于此。
    githmb
    githmb
    Aug 11, 2023
    27
    那 Rust 就不算原生支持了吗
    Huelse
    Huelse
    Aug 11, 2023
    28
    实际上都是跑在系统线程上的,只是调度方式不同罢了。
    cosmain
    cosmain
    Aug 11, 2023❤️1
    29
    cosmain
    cosmain
    Aug 11, 2023
    30
    IO 多路复用需要系统底层提供支持来实现一个线程中监控多个文件描述符的 IO 事件,但是通常你去真正读写的时候,还是会打开新的线程。

    协程是一个语言层面的抽象,只需要语言提供库和特性,和系统底层无关,通常是用户态的“技巧”,旨在在一个线程中处理多个“task”,达到减少内核线程存储、上下文切换等开销。
    mmdsun
    mmdsun
    Aug 11, 2023
    31
    正意义上的协程??到现在协程本身没有一个统一的定义吧,而是一个广泛的概念。
    https://en.wikipedia.org/wiki/Coroutine

    其实用汇编也能做到的,不一定需要基于 epoll/select 机制。
    而且这个也不是异步 IO 。IOCP 、Linux 5.1 以后的 io_uring 了解下。

    协程和 IO 多路复用关联不是很强。通常说协程是一种编写并发代码的方式,可以在某些点暂停和恢复它们的执行不阻塞主线程。

    你用 goto 、lablel 跳转+状体机写,也能算 coroutine 吧?( stackless coroutine )
    FlashEcho
    FlashEcho
    Aug 11, 2023
    32
    C++20 也有协程了,也是任何条件下可以用的函数
    wanguorui123
    wanguorui123
    Aug 11, 2023
    33
    协程、虚拟线程、事件队列,实现目的都类似
    wonderblank
    wonderblank
    Aug 11, 2023
    34
    > 大部分语言的协程都是基于 epoll/select 机制,由于 epoll/select 只能处理 IO 问题,所以导致大部分语言的协程也只能处理 IO 问题

    不正确,协程和 epoll 不是一个东西,也不是说基于什么。你可以理解为协程是香蕉,epoll 是体重。epoll / select / kqueue 是多路复用的实现方案而已。可以配合协程使用。


    > 而 go 语言的协程可以在任何情况下使用,是真正意义上的协程,底层是通过汇编指令 pop/push 保存上下文

    不正确,首先没办法定义`真正意义上的协程`是什么,以及底层基本上都一样。

    > 以上理解正确吗?

    全部不正确

    基本上可以用任何语言实现协程。

    @wanguorui123

    > 协程、虚拟线程、事件队列,实现目的都类似

    不正确。设计他们,以及背后的原因都各不相同。对于特定的问题没有银弹,所以出现了很多方案。
    w950888
    w950888
    Aug 11, 2023
    35
    @WebKit kotlin 标准库不支持协程
    oxromantic
    oxromantic
    Aug 11, 2023
    36
    lua 是在 bytecode 层面的协程,用的 longjmp ,完全不用线程等机制
    zjsxwc
    zjsxwc
    Aug 11, 2023
    37
    完整的协程,php8.1 也有
    https://www.v2ex.com/t/953310#reply0
    vizee
    vizee
    Aug 11, 2023
    38
    先问是不是,再问为什么
    wanguorui123
    wanguorui123
    Aug 11, 2023
    39
    @wonderblank 设计目的都是为了高吞吐量,榨干系统性能
    luoqeng
    luoqeng
    Aug 11, 2023
    40
    问题的关键应该是协程调度器实现
    其他语言库一般用来处理网络 io ,只是利用 epoll/select 来实现调度器,Go 没有依赖 io 复用来实现调度器
    wetalk
    wetalk
    Aug 11, 2023
    41
    回到线程的定义:操作系统能够进行运算调度的最小单位。协程不是必须的
    wonderblank
    wonderblank
    Aug 11, 2023
    42
    @wanguorui123

    > 设计目的都是为了高吞吐量,榨干系统性能

    你年纪太小了,也不能说你错。
    charlie21
    charlie21
    Aug 11, 2023
    43
    Golang 采用的 CSP 模型和 Erlang 的 Actor 模型
    https://zhuanlan.zhihu.com/p/27341488
    julyclyde
    julyclyde
    Aug 11, 2023
    44
    能提出这种问题,说明思维方式有问题
    bthulu
    bthulu
    Aug 12, 2023
    45
    epoll 又不是什么牛逼机制, 纯属微软作死导致 epoll 在服务端一家独大. 你可以试试 iocp, 比 epoll 强多了, 偏偏支持的没几个.
    inshua
    inshua
    Aug 12, 2023
    46
    erlang 早就有了,那几年 erlang 火了一阵,后来实在太非主流了用的就少了,但是设计思想传播出去了就有了一堆衍生,当然协程出现的更早,但是在并发领域用协程 erlang 应该算是早的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1866 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 92ms · UTC 09:52 · PVG 17:52 · LAX 01:52 · JFK 04:52
    ♥ Do have faith in what you're doing.