在Kotlin中是否有一种与另一种语言的协同实现不同的特定语言实现?
这是我开始的10万条合作项目。这段代码背后会发生什么?
for(i in 0..100000){
async(CommonPool){
// Run long-running operations
}
}发布于 2017-03-25 23:47:01
因为我只在JVM上使用协同服务,所以我将讨论JVM后端。还有Kotlin原住民和Kotlin JavaScript,但是这些Kotlin的后端超出了我的范围。
那么,让我们从比较Kotlin协同和其他语言的协同作用开始。基本上,您应该知道有两种类型的协同:无堆栈和堆栈。Kotlin实现了无堆栈的协同,这意味着coroutine没有自己的堆栈,并且限制了coroutine所能做的事情。你可以读到一个很好的解释这里。
示例:
协同线像一个轻量级线程是什么意思?
这意味着coroutine在Kotlin中没有自己的堆栈,它不映射在本机线程上,它不需要在处理器上切换上下文。
有什么关系?
线程先发制人多任务处理。(通常.协同-协同多任务处理。
由OS管理的线程(通常)。协同服务-由用户管理。
Kotlin协同线实际上是并行(并发)运行的吗?
那得看情况。您可以在自己的线程中运行每个协同线,也可以在一个线程或某个固定线程池中运行所有协同线程。
有关协同执行方式的更多信息是这里。
即使在多核系统中,在任何给定的时间也只有一个协同线在运行吗?
不,见前面的答案。
这是我开始的10万条合作项目。这段代码背后会发生什么?
实际上这要看情况。但是假设您编写了以下代码:
fun main(args: Array<String>) {
for (i in 0..100000) {
async(CommonPool) {
delay(1000)
}
}
}此代码立即执行。
因为我们需要等待async调用的结果。
所以让我们来解决这个问题:
fun main(args: Array<String>) = runBlocking {
for (i in 0..100000) {
val job = async(CommonPool) {
delay(1)
println(i)
}
job.join()
}
}当您运行此程序时,Kotlin将创建2* 100000个Continuation实例,这将占用几十MB内存,在控制台中,您将看到从1到100000之间的数字。
让我们以这样的方式重写这段代码:
fun main(args: Array<String>) = runBlocking {
val job = async(CommonPool) {
for (i in 0..100000) {
delay(1)
println(i)
}
}
job.join()
}我们现在取得了什么成就?现在,我们只创建了100,001个Continuation实例,这要好得多。
每个创建的延续都将在CommonPool (这是ForkJoinPool的静态实例)上调度和执行。
发布于 2017-04-05 13:39:58
协同线像一个轻量级线程是什么意思?
Coroutine与线程一样,表示与其他协同(线程)并行执行的一系列操作。
有什么关系?
线程直接链接到相应操作系统(操作系统)中的本机线程,并消耗大量资源。特别是,它为堆栈消耗了大量内存。这就是为什么不能只创建100 k线程的原因。你可能会失去记忆。线程之间的切换涉及操作系统内核调度程序,就CPU周期而言,这是一个非常昂贵的操作。
另一方面,协同线纯粹是用户级的语言抽象。它不绑定任何本地资源,在最简单的情况下,只使用JVM堆中一个相对较小的对象。这就是为什么很容易创建100 K协同线的原因。coroutines之间的切换根本不涉及操作系统内核。它可以像调用常规函数一样便宜。
Kotlin协同线实际上是并行(并发)运行的吗?即使在多核系统中,在任何给定的时间也只有一个协同线在运行吗?
协同线可以运行,也可以挂起。挂起的协同线不与任何特定的线程相关联,但是运行的协同线在某些线程上运行(使用线程是在OS进程中执行任何操作的唯一方法)。无论不同的协同器都运行在同一个线程上(因此,在多核系统中只能使用一个CPU )还是在不同的线程(因此可以使用多个CPU)上运行,这完全是由使用coroutines的程序员掌握的。
在Kotlin,协同线的调度是通过协同线上下文来控制的。您可以在kotlinx.coroutines指南中读到更多的相关信息。
这是我开始的10万条合作项目。这段代码背后会发生什么?
假设您正在使用launch函数和来自kotlinx.coroutines项目(这是开放源码)的CommonPool上下文,您可以在这里检查它们的源代码:
launch在这里被定义为https://github.com/Kotlin/kotlinx.coroutines/blob/master/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Builders.ktCommonPool在这里被定义为https://github.com/Kotlin/kotlinx.coroutines/blob/master/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CommonPool.ktlaunch只创建新的协同线,而CommonPool则向使用多个线程的ForkJoinPool.commonPool()分派协同值,因此在本例中在多个CPU上执行。
launch调用后的代码在{...}中称为挂起的lambda。它是什么?挂起lambda和函数是如何实现(编译)的,以及标准库函数和类(如startCoroutines、suspendCoroutine和CoroutineContext )如何在相应的Kotlin协同设计文档中进行解释。
https://stackoverflow.com/questions/43021816
复制相似问题