Saltar al contenido

¿Diferencia entre subrutina, co-rutina, función e hilo?

Posterior a de una prolongada búsqueda de datos hemos podido solucionar esta dificultad que pueden tener algunos lectores. Te compartimos la solución y esperamos servirte de gran ayuda.

Solución:

Hasta que recibamos una publicación de alguien que realmente sepa, así es como entiendo la pregunta, FWIW.

Una subrutina y una función son esencialmente lo mismo, con una diferencia: una función devuelve algún tipo de valor (generalmente a través de la pila o el registro de la CPU), mientras que una subrutina no lo hace. Ya sea una subrutina o una función, es un bloque de código ejecutable que tiene exactamente un punto de entrada. Una co-rutina también es un bloque de código ejecutable y, al igual que una subrutina, tiene un punto de entrada. Sin embargo, también tiene uno o más puntos de reingreso. Más sobre esto más adelante.

Antes de llegar a los subprocesos, repasemos: un programa de computadora, también conocido como proceso, generalmente tendrá su asignación de memoria organizada en un espacio de código, un montón y una pila. El espacio de código almacena uno o más bloques de su código ejecutable. La pila almacena los parámetros, las variables automáticas y las direcciones de retorno de las subrutinas, funciones y co-rutinas (y otras cosas también). El montón es el espacio de memoria completamente abierto disponible para el proceso para cualquiera que sea su propósito. Además de estos espacios de memoria están los registros de la CPU, cada uno de los cuales almacena un conjunto de bits. Estos bits pueden ser un valor entero, una dirección de memoria, un montón de indicadores de estado o lo que sea. La mayoría de los programadores no necesitan saber mucho sobre ellos, pero están ahí y son esenciales para el funcionamiento de la CPU. Probablemente, los que vale la pena conocer son el Contador de programas, el Puntero de pila y el Registro de estado, pero no vamos a entrar en ellos aquí.

Un subproceso es un único flujo lógico de ejecución. En un sistema informático primitivo, solo hay un hilo disponible para un proceso. En los sistemas informáticos modernos, un proceso se compone de uno o más subprocesos. Cada subproceso obtiene su propia pila y conjunto de registros de CPU (lo que generalmente es físicamente imposible, pero lógicamente se vuelve virtual, un detalle que omitiremos aquí). Sin embargo, aunque cada subproceso de un proceso tiene su propia pila y registros, todos compartirán el mismo montón y espacio de código. También (presumiblemente) se ejecutan simultáneamente; algo que realmente puede suceder en una CPU multinúcleo. Por lo tanto, dos o más partes de su programa pueden ejecutarse al mismo tiempo.

Regreso a la co-rutina: Como se mencionó anteriormente, tiene uno o más puntos de reingreso. Un punto de reingreso significa que la co-rutina puede permitir que algún otro bloque de código fuera de sí mismo tenga algún tiempo de ejecución, y luego, en algún momento futuro, hacer que el tiempo de ejecución se reanude dentro de su propio bloque de código. Esto implica que los parámetros y las variables automáticas de la co-rutina se conservan (y se restauran si es necesario) cada vez que la ejecución se cede a un bloque de código externo y luego vuelve a la de la co-rutina. Una rutina conjunta es algo que no se implementa directamente en todos los lenguajes de programación, aunque es común a muchos lenguajes ensambladores. En cualquier caso, es posible implementar una co-rutina de forma conceptual. Hay un buen artículo sobre co-rutinas en http://en.wikipedia.org/wiki/Coroutine.

Me parece que hay dos motivaciones principales para implementar un patrón de diseño co-rutinario: (1) superar las limitaciones de un proceso de subproceso único; y (2) con la esperanza de lograr un mejor rendimiento computacional. La motivación (1) es clara de entender cuando el proceso debe abordar muchas cosas a la vez donde un solo hilo es imprescindible. La motivación (2) puede no ser tan clara de entender, ya que está ligada a muchos detalles sobre el hardware del sistema, el diseño del compilador y el diseño del lenguaje. Solo puedo imaginar que el esfuerzo computacional podría reducirse al reducir las manipulaciones de la pila, evitar rehacer las inicializaciones en una subrutina o aliviar parte de la sobrecarga de mantener un proceso de subprocesos múltiples.

HTH

Centrándonos en la corrutina frente a la subrutina:

Las corrutinas pueden producir y esto es interesante

Yield ‘recuerda’ dónde está la co-rutina, de modo que cuando se vuelve a llamar, continuará donde se quedó.

Por ejemplo:

  coroutine foo 
    yield 1;
    yield 2;
    yield 3;
  
  print foo();
  print foo();
  print foo();

Impresiones: 1 2 3

Nota: las corrutinas pueden usar un retorno y comportarse como una subrutina

  coroutine foo 
    return 1;
    return 2; //Dead code
    return 3;
  
  print foo();
  print foo();
  print foo();

Impresiones: 1 1 1

Me gustaría ampliar las respuestas existentes, agregando lo siguiente:
Existen 4 conceptos principales en la invocación de una pieza de código:

  1. creación de un contexto (también conocido como “marco”, un entorno local para que este código funcione)
  2. reanudación/invocación de un contexto (transferencia de control a ese marco, también conocido como salto)
  3. separar (reanudar otro contexto, similar a 2.)
  4. y destrucción de un contexto

En las subrutinas, la creación y la reanudación ocurren simultáneamente con una instrucción de “llamada”: se asigna un marco de pila, se empujan los argumentos y la dirección de retorno, la ejecución salta a la pieza de código llamada. Además, la separación (reanudación de una persona que llama) y la destrucción se realizan simultáneamente con una instrucción de “retorno”: el marco de la pila se desasigna, el control se transfiere a una persona que llama (a través de la dirección de retorno proporcionada previamente) y se deja que la persona que llama recoja la basura en una pila para seleccionar el valor de retorno (dependiendo de sus convenciones de llamada).
En las corrutinas, estos conceptos principales existen de forma independiente, desacoplados entre sí. Usted crea una rutina en algún momento, luego puede transferirle el control más tarde (para que pueda generar algunos resultados, posiblemente varias veces), y luego puede destruirla en algún momento posterior.

Recuerda algo, que tienes el privilegio glosar si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *