unity corrutinas use-case coroutine

use-case - corrutinas - coroutine unity



¿Cuáles son los casos de uso para una corrutina? (7)

Las corutinas reales requieren soporte de sus herramientas: deben ser implementadas por el compilador y respaldadas por el marco subyacente.

Un ejemplo del mundo real de Coroutines se encuentra con la palabra clave "yield return" proporcionada en C # 2.0, que le permite escribir un método que devuelve múltiples valores para el bucle.

Sin embargo, el "rendimiento de rendimiento" tiene limitaciones: la implementación utiliza una clase de ayuda para capturar el estado, y solo admite un caso específico de corrutina como generador (iterador).

En el caso más general, la ventaja de Coroutines es que hacen que ciertos cálculos basados ​​en estados sean mucho más fáciles de expresar y fáciles de entender: la implementación de una máquina de estado como un conjunto de corutinas puede ser más elegante que los enfoques más comunes . Pero hacer esto requiere soporte y herramientas que aún no existen en C # o Java.

El concepto de coroutine suena muy interesante, pero no sé si tiene sentido en un entorno productivo real. ¿Qué son los casos de uso para corutinas, que se pueden resolver de forma más elegante, más simple o más eficiente que con otros métodos?


Las corutinas son útiles para implementar patrones de productor / consumidor.

Por ejemplo, Python introdujo coroutines en una función de lenguaje llamada generadores , que pretendía simplificar la implementación de iteradores.

También pueden ser útiles para implementar la multitarea cooperativa, donde cada tarea es una corutina que cede a un programador / reactor.


Algunas buenas respuestas que describen qué corutinas son.

Pero para un caso de uso real. Toma un servidor web. Tiene múltiples conexiones simultáneas, y quiere programar la lectura y escritura de todas ellas.

Esto se puede implementar usando coroutines. Cada conexión es una corutina que lee / escribe una pequeña cantidad de datos, luego "cede" el control al programador, que pasa a la siguiente corutina (que hace lo mismo) mientras recorremos todas las conexiones disponibles.


Muchos de ellos, por ejemplo:

grep TODO *.c *.h | wc -l

La canalización anterior es exactamente una corutina: el comando grep genera una secuencia de líneas que van a un buffer, el comando wc "se las come"; si el buffer se llena, el grep "bloquea" hasta que se vacía el buffer, y si el buffer está vacío, el comando wc espera nuevas entradas.

Lo que pasa con las coroutinas es que, en la mayoría de los casos, ahora se usan en patrones más restringidos, como los generadores Python mencionados, o como tuberías.

Si quieres verlos más de cerca, mira los artículos de Wikipedia, especialmente sobre corrutinas e iteradores .


Como un ejemplo más específico en la línea de productores / consumidores, algo tan simple como el humilde programa de informes por lotes podría usar co-rutinas.

La pista clave para ese ejemplo es tener un trabajo no trivial para consumir datos de entrada (por ejemplo, analizar datos o acumular cargos y pagos en una cuenta), y un trabajo no trivial para producir el resultado. Cuando tienes estas características:

  • Es fácil organizar / entender el código del lado de entrada si puede "emitir" unidades de trabajo en varios lugares.
  • También es fácil organizar / comprender el código del lado de salida si puede "agarrar" la siguiente unidad de trabajo en una estructura de control anidada.

luego coronetas y colas son buenas técnicas para tener a su disposición.


Coroutines puede ser útil cada vez que un sistema tiene dos o más piezas de código cuya representación más natural sería como una serie secuencial de pasos que implican una gran cantidad de espera.

Por ejemplo, considere un dispositivo que tenga una interfaz de usuario de teclado y LCD y un módem, y necesite usar el módem para llamar e informar periódicamente su estado independientemente de lo que esté haciendo el usuario en el teclado. La mejor manera de escribir la interfaz de usuario puede ser usar funciones como "input_numeric_value (& CONV_SPEED_FORMAT, & conveyor_speed);" que volverá cuando un usuario haya ingresado un valor, y la mejor forma de manejar la comunicación puede ser funciones de uso como "wait_for_carrier ();" que volverá cuando la unidad se haya conectado o haya determinado que no va a funcionar.

Sin corutinas, el subsistema de IU o el subsistema de módem tendrían que implementarse utilizando una máquina de estados. El uso de corrutinas hace posible que ambos subsistemas se escriban con el estilo más natural. Tenga en cuenta que es importante que ninguno de los subsistemas pase mucho tiempo sin poner las cosas en un estado "consistente" y llame a yield (), ni llama a yield () sin poner primero las cosas en un estado "consistente", pero generalmente no es difícil cumplirlas restricciones

Tenga en cuenta que si bien se podría utilizar la multitarea en toda regla, eso requiere el uso de bloqueos en cualquier lugar en cualquier momento en que se modifique el estado compartido. Como el conmutador de coroutine nunca cambiará cosas excepto en las llamadas a yield (), cualquiera de las rutinas puede alterar libremente el estado compartido siempre que asegure que todo esté en orden antes del próximo rendimiento y esté preparado para que la otra rutina altere el estado ". durante "el rendimiento ().


Sé que han pasado casi 5 años desde que se formuló la pregunta, pero me sorprende que nadie haya mencionado el caso de uso de los juegos donde las corotinas se usan mucho para medir el tiempo de un cálculo.

Para mantener una velocidad de fotogramas constante en un juego, digamos 60 fps, tienes aproximadamente 16.6ms para ejecutar el código en cada fotograma. Eso incluye simulación de física, procesamiento de entrada, dibujo / pintura.

Digamos que su método se ejecuta en cada fotograma. Si su método tarda mucho tiempo y termina abarcando varios fotogramas, va a escalonar el resto del cálculo en el bucle del juego, lo que hace que el usuario vea "jank".

Lo que las corutinas le permiten hacer es, de alguna manera, cortar el tiempo de este cálculo para que se ejecute un poco en cada cuadro.

Para que eso suceda, corutinas esencialmente permite que el método "ceda" el cálculo a la "persona que llama" (en este caso, el bucle del juego) para que la próxima vez que se llame al método se reanude desde donde lo dejó.