Revisamos profundamente cada tutoriales de nuestro espacio con la meta de enseñarte en todo momento información más veraz y actual.
Solución:
Primera lectura: Concurrencia vs Paralelismo – ¿Cuál es la diferencia?
La concurrencia es la separación de tareas para proporcionar ejecución intercalada. El paralelismo es la ejecución simultánea de múltiples trabajos para aumentar la velocidad. —Https: //github.com/servo/servo/wiki/Design
Respuesta corta: Con los subprocesos, el sistema operativo cambia los subprocesos en ejecución de forma preventiva de acuerdo con su planificador, que es un algoritmo en el kernel del sistema operativo. Con las corrutinas, el programador y el lenguaje de programación determinan cuándo cambiar las corrutinas; en otras palabras, las tareas son multitarea cooperativamente pausando y reanudando funciones en puntos establecidos, típicamente (pero no necesariamente) dentro de un solo hilo.
Respuesta larga: A diferencia de los subprocesos, que son programados de forma preventiva por el sistema operativo, los conmutadores de rutina son cooperativos, lo que significa que el programador (y posiblemente el lenguaje de programación y su tiempo de ejecución) controla cuándo se producirá un cambio.
A diferencia de los subprocesos, que son preventivos, los interruptores de rutina son cooperativos (el programador controla cuándo sucederá un cambio). El kernel no está involucrado en los cambios de rutina. —Http: //www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html/coroutine/overview.html
Un idioma que apoya hilos nativos puede ejecutar sus subprocesos (subprocesos de usuario) en los subprocesos del sistema operativo (hilos de kernel). Cada proceso tiene al menos un hilo de kernel. Los subprocesos del kernel son como procesos, excepto que comparten espacio de memoria en su proceso de propiedad con todos los demás subprocesos en ese proceso. Un proceso “posee” todos sus recursos asignados, como memoria, identificadores de archivos, sockets, identificadores de dispositivos, etc., y todos estos recursos se comparten entre los subprocesos del kernel.
El programador del sistema operativo es parte del kernel que ejecuta cada subproceso durante una cierta cantidad de tiempo (en una máquina con un solo procesador). El programador asigna tiempo (reparto de tiempo) a cada hilo, y si el hilo no termina dentro de ese tiempo, el programador se adelanta (lo interrumpe y cambia a otro hilo). Se pueden ejecutar varios subprocesos en paralelo en una máquina multiprocesador, ya que cada subproceso puede programarse (pero no necesariamente tiene que estar) programado en un procesador separado.
En una máquina con un solo procesador, los subprocesos se dividen en intervalos de tiempo y se sustituyen (cambian entre) rápidamente (en Linux, el intervalo de tiempo predeterminado es 100 ms), lo que los hace concurrentes. Sin embargo, no se pueden ejecutar en paralelo (simultáneamente), ya que un procesador de un solo núcleo solo puede ejecutar una cosa a la vez.
Corutinas y / o generadores se puede utilizar para implementar funciones cooperativas. En lugar de ejecutarse en subprocesos del kernel y programarse por el sistema operativo, se ejecutan en un solo subproceso hasta que ceden o terminan, cediendo a otras funciones determinadas por el programador. Idiomas con generadores, como Python y ECMAScript 6, se pueden utilizar para crear corrutinas. Async / await (visto en C #, Python, ECMAscript 7, Rust) es una abstracción construida sobre funciones generadoras que producen futuros / promesas.
En algunos contextos, corrutinas puede referirse a funciones apiladas mientras generadores puede referirse a funciones sin pila.
Fibras, hilos ligeros, y hilos verdes son otros nombres para corrutinas o cosas similares a las corrutinas. A veces pueden parecer (típicamente a propósito) más como subprocesos del sistema operativo en el lenguaje de programación, pero no se ejecutan en paralelo como subprocesos reales y funcionan como corrutinas. (Puede haber particularidades técnicas más específicas o diferencias entre estos conceptos según el lenguaje o la implementación).
Por ejemplo, Java tenía “hilos verdes“; estos eran subprocesos que fueron programados por la máquina virtual Java (JVM) en lugar de de forma nativa en los subprocesos del kernel del sistema operativo subyacente. Estos no se ejecutaron en paralelo ni aprovecharon múltiples procesadores / núcleos, ya que eso requeriría un subproceso nativo Dado que no fueron programados por el sistema operativo, se parecían más a corrutinas que a subprocesos del kernel.Los subprocesos verdes son los que utilizaba Java hasta que se introdujeron los subprocesos nativos en Java 1.2.
Los subprocesos consumen recursos. En la JVM, cada subproceso tiene su propia pila, normalmente de 1 MB de tamaño. 64k es la menor cantidad de espacio de pila permitido por subproceso en la JVM. El tamaño de la pila de subprocesos se puede configurar en la línea de comandos para la JVM. A pesar del nombre, los subprocesos no son gratuitos, debido a su uso de recursos, como que cada subproceso necesita su propia pila, almacenamiento local de subprocesos (si lo hay) y el costo de la programación de subprocesos / cambio de contexto / invalidación de caché de CPU. Esta es parte de la razón por la que las corrutinas se han vuelto populares para aplicaciones altamente concurrentes y críticas para el rendimiento.
Mac OS solo permitirá que un proceso asigne alrededor de 2000 subprocesos, y Linux asigna una pila de 8 MB por subproceso y solo permitirá tantos subprocesos que quepan en la RAM física.
Por lo tanto, los subprocesos tienen el peso más pesado (en términos de uso de memoria y tiempo de cambio de contexto), luego las corrutinas y, finalmente, los generadores son los más livianos.
Las corrutinas son una forma de procesamiento secuencial: solo una se está ejecutando en un momento dado (al igual que las subrutinas AKA procedimientos AKA funciones, simplemente se pasan el testigo entre sí de manera más fluida).
Los subprocesos son (al menos conceptualmente) una forma de procesamiento concurrente: varios subprocesos pueden estar ejecutándose en un momento dado. (Tradicionalmente, en máquinas de un solo núcleo y CPU única, esa simultaneidad se simulaba con algo de ayuda del sistema operativo; hoy en día, dado que muchas máquinas son de múltiples CPU y / o múltiples núcleos, los subprocesos de facto estar ejecutándose simultáneamente, no solo “conceptualmente”).
Aproximadamente 7 años tarde, pero a las respuestas aquí les falta algo de contexto sobre co-rutinas vs hilos. Por qué son corrutinas recibiendo tanta atención últimamente, y cuándo los usaría en comparación con hilos?
En primer lugar, si se ejecutan corrutinas al mismo tiempo (nunca en paralelo), ¿por qué alguien los preferiría a los hilos?
La respuesta es que las corrutinas pueden proporcionar una muy alto nivel de concurrencia con muy poca sobrecarga. Generalmente, en un entorno con subprocesos, tiene como máximo 30-50 subprocesos antes de que la cantidad de sobrecarga desperdiciada realmente programe estos subprocesos (por el programador del sistema) significativamente reduce la cantidad de tiempo que los hilos realmente hacen un trabajo útil.
De acuerdo, con los subprocesos puede tener paralelismo, pero no demasiado paralelismo, ¿no es eso aún mejor que una co-rutina que se ejecuta en un solo subproceso? Bueno, no necesariamente. Recuerde que una co-rutina aún puede realizar simultaneidad sin la sobrecarga del programador; simplemente administra el cambio de contexto en sí.
Por ejemplo, si tiene una rutina haciendo algún trabajo y realiza una operación que sabe que se bloqueará durante algún tiempo (es decir, una solicitud de red), con una co-rutina puede cambiar inmediatamente a otra rutina sin la sobrecarga de incluir el programador del sistema en esta decisión – sí, el programador debe especificar cuándo pueden cambiar las co-rutinas.
Con una gran cantidad de rutinas que realizan un trabajo muy pequeño y que se alternan voluntariamente entre sí, ha alcanzado un nivel de eficiencia que ningún programador podría esperar alcanzar. Ahora puede tener miles de corrutinas trabajando juntas en lugar de decenas de subprocesos.
Debido a que sus rutinas ahora cambian entre sí en puntos predeterminados, ahora también puede evitar bloquear en estructuras de datos compartidas (porque nunca le diría a su código que cambie a otra corrutina en medio de una sección crítica)
Otro beneficio es el uso de memoria mucho menor. Con el modelo de subprocesos, cada subproceso necesita asignar su propia pila, por lo que su uso de memoria crece linealmente con la cantidad de subprocesos que tiene. Con las co-rutinas, la cantidad de rutinas que tiene no tiene una relación directa con su uso de memoria.
Y finalmente, las co-rutinas están recibiendo mucha atención porque en algunos lenguajes de programación (como Python) su los hilos no pueden correr en paralelo de todos modos – se ejecutan simultáneamente como corrutinas, pero sin la poca memoria y la sobrecarga de programación libre.
Reseñas y puntuaciones
Nos puedes añadir valor a nuestro contenido contribuyendo tu veteranía en las reseñas.