V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
winterbells
V2EX  ›  问与答

协程的原理还是没懂

  •  
  •   winterbells · 2020-05-06 23:12:43 +08:00 · 4366 次点击
    这是一个创建于 1660 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网上看的文章都是讲了 Kotlin 编译后,有个 continuation,有个状态机 怎么在线程中挂起,又是怎么在耗时操作结束后恢复的有点理解不了 没学过这种底层的东西,看得云里雾里的 qaq

    16 条回复    2020-11-26 15:18:16 +08:00
    vk42
        1
    vk42  
       2020-05-06 23:43:22 +08:00   ❤️ 2
    简单理解就是把多线程任务挤到同一个线程内,通过协程原语进行交互交替执行,但因为本质是单线程所以省去了同步机制开销。如果你原先对多线程熟悉应该会更方便理解
    aabbcc112233
        2
    aabbcc112233  
       2020-05-06 23:46:51 +08:00
    @vk42 所以你知道 kotlin 的协程真的是真协程吗
    vk42
        3
    vk42  
       2020-05-07 00:40:10 +08:00
    @aabbcc112233 kotlin 还真不了解,不同语言实现协程机制肯定有区别,但协程本来就是从汇编就有了的老概念了,实现上也没什么难度,只要概念本质是对的,无所谓真假吧
    WebKit
        4
    WebKit  
       2020-05-07 00:47:38 +08:00 via Android   ❤️ 1
    @aabbcc112233 kotlin 的协程只是对线程的封装,类似 rxjava
    silvernoo
        5
    silvernoo  
       2020-05-07 01:39:39 +08:00   ❤️ 1
    协程应该就是一种实现把,主要的思想是异步和非阻塞把
    lzdhlsc
        6
    lzdhlsc  
       2020-05-07 05:23:29 +08:00   ❤️ 1
    coroutine == resumable function
    winterbells
        7
    winterbells  
    OP
       2020-05-07 08:09:30 +08:00 via Android
    @vk42 这个知道了,但它是怎么挂起的、怎么 delay 的,又是怎么在一段时间后恢复的,还是不清楚
    hanxiV2EX
        8
    hanxiV2EX  
       2020-05-07 08:47:50 +08:00 via Android   ❤️ 1
    就跟 c 语言的 goto 差不多,执行到某个地方 yield,函数就 return 了,再 resume 的时候又回到了上次 yield 的地方。只不过协程会帮你把函数堆栈都存好了,goto 回来的时候能继续找到上下文。
    ica10888
        9
    ica10888  
       2020-05-07 08:53:27 +08:00 via Android   ❤️ 2
    我想说 callcc,怕直接绕晕了...
    129tyc
        10
    129tyc  
       2020-05-07 09:06:29 +08:00 via Android   ❤️ 1
    协程的挂起可以通过 yield 主动放弃对 cpu 的占有,恢复则是由其他协程或调度器主动将其 resume,delay 只是挂起和恢复的组合,功能和效果上和线程的 delay 类似
    Cabana
        11
    Cabana  
       2020-05-07 09:15:30 +08:00 via Android   ❤️ 1
    jvm 的 kotlin 协程只是对线程调度的封装而已
    jswh
        12
    jswh  
       2020-05-07 09:33:04 +08:00   ❤️ 1
    传统意义上的协程是基于生成器的,可以在函数执行中间主动让出 cpu 占用,在下次调用的时候恢复函数上下文从中断的地方恢复执行,常见的语法就是 yield 。生成器语法只是提供了主动让出 cpu 占用的能力,要做到实用的协程一般还要搭配一个调度器,golang 语言自带,php 的 swoole,python tornado 等。同时所有相关库( io,网络等)都要用生成器形式来写在等待的时候让出 cpu,不然也没啥异步能力。
    itskingname
        13
    itskingname  
       2020-05-07 09:40:23 +08:00   ❤️ 2
    如果你看得懂 Python,我写了一篇 Python 相关的: https://mp.weixin.qq.com/s/spayiLNuTnFVOWWeW-jkwQ
    vk42
        14
    vk42  
       2020-05-07 10:28:58 +08:00   ❤️ 1
    @winterbells
    挂起恢复都是具体语言实现细节,你要看你所指的语言特性了。比如汇编可以用 long jump 来实现,c 可以用 goto 实现等等……
    wysnylc
        15
    wysnylc  
       2020-05-07 10:40:04 +08:00   ❤️ 1
    协程相关:
    [Kotlin 协程真的比 Java 线程更高效吗?]( https://cloud.tencent.com/developer/article/1570462)
    [为什么 Java 坚持多线程不选择协程?]( https://www.zhihu.com/question/332042250)
    Mrag
        16
    Mrag  
       2020-11-26 15:18:16 +08:00
    与事件驱动的机制很相似
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2788 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 13:43 · PVG 21:43 · LAX 05:43 · JFK 08:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.