首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin中线程和协同线的区别

Kotlin中线程和协同线的区别
EN

Stack Overflow用户
提问于 2017-03-25 20:50:57
回答 2查看 27.6K关注 0票数 106

在Kotlin中是否有一种与另一种语言的协同实现不同的特定语言实现?

  • 协同线像一个轻量级线程是什么意思?
  • 有什么关系?
  • Kotlin协同线实际上是并行(并发)运行的吗?
  • 即使在多核系统中,在任何给定的时间也只有一个协同线在运行吗?

这是我开始的10万条合作项目。这段代码背后会发生什么?

代码语言:javascript
复制
for(i in 0..100000){
   async(CommonPool){
    // Run long-running operations
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-25 23:47:01

因为我只在JVM上使用协同服务,所以我将讨论JVM后端。还有Kotlin原住民和Kotlin JavaScript,但是这些Kotlin的后端超出了我的范围。

那么,让我们从比较Kotlin协同和其他语言的协同作用开始。基本上,您应该知道有两种类型的协同:无堆栈和堆栈。Kotlin实现了无堆栈的协同,这意味着coroutine没有自己的堆栈,并且限制了coroutine所能做的事情。你可以读到一个很好的解释这里

示例:

  • 无堆栈: C#,Scala,Kotlin
  • Stackful:类星体,Javaflow

协同线像一个轻量级线程是什么意思?

这意味着coroutine在Kotlin中没有自己的堆栈,它不映射在本机线程上,它不需要在处理器上切换上下文。

有什么关系?

线程先发制人多任务处理。(通常.协同-协同多任务处理。

由OS管理的线程(通常)。协同服务-由用户管理。

Kotlin协同线实际上是并行(并发)运行的吗?

那得看情况。您可以在自己的线程中运行每个协同线,也可以在一个线程或某个固定线程池中运行所有协同线程。

有关协同执行方式的更多信息是这里

即使在多核系统中,在任何给定的时间也只有一个协同线在运行吗?

不,见前面的答案。

这是我开始的10万条合作项目。这段代码背后会发生什么?

实际上这要看情况。但是假设您编写了以下代码:

代码语言:javascript
复制
fun main(args: Array<String>) {
    for (i in 0..100000) {
        async(CommonPool) {
            delay(1000)
        }
    }
}

此代码立即执行。

因为我们需要等待async调用的结果。

所以让我们来解决这个问题:

代码语言:javascript
复制
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之间的数字。

让我们以这样的方式重写这段代码:

代码语言:javascript
复制
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的静态实例)上调度和执行。

票数 85
EN

Stack Overflow用户

发布于 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只创建新的协同线,而CommonPool则向使用多个线程的ForkJoinPool.commonPool()分派协同值,因此在本例中在多个CPU上执行。

launch调用后的代码在{...}中称为挂起的lambda。它是什么?挂起lambda和函数是如何实现(编译)的,以及标准库函数和类(如startCoroutinessuspendCoroutineCoroutineContext )如何在相应的Kotlin协同设计文档中进行解释。

票数 98
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43021816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档