Diferencia entre hilo y coroutine en Kotlin

¿Existe alguna implementación de lenguaje específica en Kotlin que la diferencie de otras corutinas de idiomas?

  • ¿Qué significa que la coroutine es como un hilo ligero?
  • ¿Cuál es la diferencia?
  • ¿Las corrutinas de kotlin se están ejecutando en paralelo / concurrentemente?
  • Incluso en el sistema multi-core, solo hay una corrutina ejecutándose en un momento dado (¿es correcto?)

Aquí estoy comenzando 100000 corutinas, ¿qué ocurre detrás de este código?

for(i in 0..100000){ async(CommonPool){ //run long running operations } } 

Como utilicé coroutines solo en JVM, hablaré sobre el backend de JVM, también hay JavaScript de Kotlin Native y Kotlin, pero esto está fuera de mi scope para Kotlin.

Comencemos por comparar las corotinas de Kotlin con corutinas de otros idiomas. Básicamente, debes saber que hay dos types de Corutinas: sin astackmiento y astackdas. Kotlin implementa corotines sin astackmiento: significa que la coroutine no tiene stack propia, y eso limita un poco lo que la corotina puede hacer. Puedes leer una buena explicación aquí .

Ejemplos:

  • Stackless: C #, Scala, Kotlin
  • Astackble: Quasar, Javaflow

¿Qué significa que la coroutine es como un hilo ligero?

Es decir que corotine en Kotlin no tiene stack propia, no se correlaciona en el hilo nativo, no requiere el cambio de context en el procesador.

¿Cuál es la diferencia?

Subprocess: multitarea preventiva. (por lo general ). Coroutine – cooperativamente multitarea.

Subprocess: administrado por SO (generalmente). Coroutine: administrado por el usuario.

¿Las corrutinas de kotlin se están ejecutando en paralelo / concurrentemente?

Depende, usted puede ejecutar cada corrutina en su propio hilo, o puede ejecutar todas las corutinas en un subprocess o en un grupo de subprocesss fijos.

Más sobre cómo se ejecuta coroutines aquí .

Incluso en el sistema multi-core, solo hay una corrutina ejecutándose en un momento dado (¿es correcto?)

No, mira la respuesta anterior.

Aquí estoy comenzando 100000 corutinas, ¿qué ocurre detrás de este código?

En realidad, eso depende. Pero supongamos que escribe el siguiente código:

 fun main(args: Array<String>) { for (i in 0..100000) { async(CommonPool) { delay(1000) } } } 

Este código se ejecuta instantáneamente.

Porque tenemos que esperar los resultados de la llamada async .

Así que arreglemos esto:

 fun main(args: Array<String>) = runBlocking { for (i in 0..100000) { val job = async(CommonPool) { delay(1) println(i) } job.join() } } 

Cuando ejecutas este progtwig, kotlin creará 2 * 100000 instancias de Continuation , que tomarán unas docenas de Mb de RAM, y en la console verás numbers del 1 al 100000.

Así que reescribamos este código de esta manera:

 fun main(args: Array<String>) = runBlocking { val job = async(CommonPool) { for (i in 0..100000) { delay(1) println(i) } } job.join() } 

¿Qué logramos ahora? Ahora creamos solo 100001 instancias de Continuation , y esto es mucho mejor.

Cada Continuación creada será enviada y ejecutada en CommonPool (que es una instancia estática de ForkJoinPool).

¿Qué significa que la coroutine es como un hilo ligero?

Coroutine, como un hilo, representa una secuencia de acciones que se ejecutan simultáneamente con otras coroutines (hilos).

¿Cuál es la diferencia?

Un hilo está directamente relacionado con el hilo nativo en el sistema operativo correspondiente (sistema operativo) y consume una cantidad considerable de resources. En particular, consume mucha memory para su stack. Es por eso que no puedes simplemente crear hilos de 100k. Es probable que se quede sin memory. El cambio entre hilos implica al asignador de núcleo del sistema operativo y es una operación bastante costosa en términos de ciclos de CPU consumidos.

Una corutina, por otro lado, es puramente una abstracción de lenguaje a nivel de usuario. No vincula ningún recurso nativo y, en el caso más simple, utiliza solo un object relativamente pequeño en el montón de JVM. Es por eso que es fácil crear 100k corutinas. El cambio entre corutinas no implica kernel de sistema operativo en absoluto. Puede ser tan barato como invocar una function regular.

¿Las corrutinas de kotlin se están ejecutando en paralelo / concurrentemente? Incluso en el sistema multi-core, solo hay una corrutina ejecutándose en un momento dado (¿es correcto?)

Una corrutina puede estar ejecutándose o suspendida. Una corutina suspendida no está asociada a ningún hilo en particular, pero una corrutina en ejecución se ejecuta en un hilo (usar un hilo es la única forma de ejecutar cualquier cosa dentro de un process del sistema operativo). Si las diferentes corotinas se ejecutan todas en el mismo subprocess (por lo tanto, pueden usar solo una CPU en un sistema multinúcleo) o en diferentes subprocesss (y pueden usar varias CPU) está en manos de un progtwigdor que está utilizando corutinas.

En Kotlin, el envío de corrutinas se controla a través del context coroutine . Puede leer más sobre eso en la Guía de kotlinx.coroutines

Aquí estoy comenzando 100000 corutinas, ¿qué ocurre detrás de este código?

Suponiendo que está utilizando la function de launch y el context kotlinx.coroutines proyecto kotlinx.coroutines (que es de código abierto), puede examinar su código fuente aquí:

El launch solo crea nueva coroutine, mientras que CommonPool distribuye coroutines a ForkJoinPool.commonPool() que usa varios hilos y, por lo tanto, se ejecuta en varias CPU en este ejemplo.

El código que sigue a la invocación de launch en {...} se llama lambda de suspensión . Qué es y cómo se implementan (comstackn) las funciones y startCoroutines , así como las funciones de biblioteca estándar y las classs como startCoroutines , suspendCoroutine y CoroutineContext se explican en el documento de layout de corotines de Kotlin correspondiente.

  • Extensiones de Kotlin para Android, los packages no se pueden importar
  • ¿Hay syntax al igual que #region #endregion en Kotlin?
  • Timeline Mission no ejecuta misiones
  • No se puede agregar y eliminar la opción de menu del fragment y del panel de navigation
  • ¿Cómo get la reference de class de KParameter en kotlin?
  • ¿Cómo recuperar y encontrar el estado actual en Spring State Machine?
  • Cómo crear callbacks de funciones anidadas como anko - syntax DSL Kotlin
  • Seguridad de spring. Página de inicio de session multilenguaje basada en url
  • Emitir cualquiera a Matriz en Kotlin
  • ¿Qué se puede express en una constante de time de compilation (const val)?
  • ¿Falta la list de Kotlin "agregar", "eliminar", etc.?