Kotlin 的协程是真协程吗?被 b 站博主搞蒙了

2022-01-25 15:51:28 +08:00
 714105382

能做到类似 golang goroutine 完全不阻塞任何 os thread 进行 io 之类的访问并在得到结果后自动把协程挂载到线程继续执行?

视频上说不能: [ [码上开学] 到底什么是「非阻塞式」挂起?协程真的比线程更轻量级吗?-哔哩哔哩] https://b23.tv/qIkWUmo

7669 次点击
所在节点    Kotlin
27 条回复
unco020511
2022-01-27 09:41:24 +08:00
@fpure # 18 是吗,那可能是我理解错了吧
kingbill
2022-03-11 16:21:18 +08:00
据我的了解,计算机领域协程没有统一的定义(要说统一可能就是线程再上层的抽象),不同语言中对协程的定义都不太一样,不像线程是依赖操作系统的。真协程……不太理解你说的
D3EP
2022-04-14 16:12:36 +08:00
协程肯定是跑在线程上的,操作系统就没有协程的概念。
「非对称协程」大多数都是类似 Kotlin 这种实现,将一个函数体拆成多个 subroutine ,执行异步操作时,通过 continuation 保存上下文状态(包括代码行号、局部变量),并从当前函数退出;当异步操作完成时,会通过 continuation 重新进入该函数,并恢复上下文。
D3EP
2022-05-04 20:00:16 +08:00
上面说错了,应该是「无栈协程」大多数都是类似 Kotlin 这种实现,将一个函数体拆成多个 subroutine ,执行异步操作时,通过 continuation 保存上下文状态(包括代码行号、局部变量),并从当前函数退出;当异步操作完成时,会通过 continuation 重新进入该函数,并恢复上下文。

Golang 那种是有栈协程。
Pantheoon
2022-09-16 20:39:52 +08:00
其实就是回调,没那么难理解,举个例子:
doSth(xxx,new Listener(){
success(){}
})
success 就是写在回调里面的,这种方式一个是比较丑陋,第二个是会有回调地狱的问题,doSth 可以跑在主线程,success 可以跑在子线程里面,后面为了解决丑陋的问题,就有了 await 这个关键字,js 和 c#都有,语法就变成了这样:
await doSth()
success()
看到没有,如果有 await 他的语法是等价于上面那种东西的,doSth 可以跑在主线程,success 跑在了子线程里面,也就是用同步的方式写异步代码,线程发生了切换,但执行的顺序是同步的,本质上是回调
然后到了 kotlin,首先,kotlin 吹嘘协程是对开发产生了误导,他的本质其实就是类似 await,通过语法把回调屏蔽掉:
launch{
doSth()
success()
}
suspend doSth()
而 suspend 关键字就是类似于 await,async 的 async 一样,其实就是打个标记,告诉编译器,后面可以加回调,当线程执行 success 时,doSth 方法没有被执行,也就是所谓的挂起来了,而添加回调的方式叫做 continuation,也就是反编译后是类似这样的语法
doSth().continuation(success())
大概这样子
Pantheoon
2022-09-16 20:43:15 +08:00
如果是通过回调的方式,除了 success 方法,还有一个 error 方法
doSth(xxx,new Listener(){
success(){}
error(){}
})
但是 kotlin 里面回调的语法是没有处理 error 的,所以它又搞了一堆异常机制,异常在协程里咋传播的,然后咋处理,设计的还挺复杂
ExplodingFKL
2022-12-16 12:44:55 +08:00
“轻量”只是相对的概念,对于 CPU 密集的任务改用协程实现并不会有显著的性能提升,协程的主要目的是尽量避免无意义的等待 .

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

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

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

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

© 2021 V2EX