Bien, piense en términos de desarrollo de juegos.
Digamos que estás haciendo una escena o tal vez un tutorial. De cualquier manera, lo que tienes es una secuencia ordenada de comandos enviados a algunas entidades. Una entidad se mueve a un lugar, habla con un hombre y luego se va a otra parte. Etcétera. Algunos comandos no pueden comenzar hasta que otros hayan terminado.
Ahora mira cómo funciona tu juego. En cada cuadro, debe procesar AI, pruebas de colisión, animación, renderizado y sonido, posiblemente entre otras cosas. Solo puedes pensar cada cuadro. Entonces, ¿cómo pones este tipo de código, donde tienes que esperar a que se complete alguna acción antes de hacer la siguiente?
Si construiste un sistema en C++, lo que tendrías es algo que se ejecutó antes que la IA. Tendría una secuencia de comandos para procesar. Algunos de esos comandos serían instantáneos, como "dile a la entidad X que vaya aquí" o "genere la entidad Y aquí". Otros tendrían que esperar, como "decirle a la entidad Z que vaya aquí y no procese más comandos hasta que haya llegado aquí". El procesador de comandos debería llamarse en cada cuadro, y debería comprender condiciones complejas como "la entidad está en la ubicación", etc.
En Lua, que se vería así:
local entityX = game:GetEntity("entityX");
entityX:GoToLocation(locX);
local entityY = game:SpawnEntity("entityY", locY);
local entityZ = game:GetEntity("entityZ");
entityZ:GoToLocation(locZ);
do
coroutine.yield();
until (entityZ:isAtLocation(locZ));
return;
del tamaño C++, podría reanudar este script una vez por cuadro hasta que se haga. Una vez que regrese, sabrá que el cutscene ha terminado, por lo que puede devolver el control al usuario.
Mire qué tan simple es esa lógica de Lua. Hace exactamente lo que dice que hace. Es claro, obvio y, por lo tanto, es muy difícil equivocarse.
El poder de coroutines es poder realizar parcialmente alguna tarea, esperar a que se cumpla una condición, luego pasar a la siguiente tarea.
Son del siglo pasado. La CPU multinúcleo y las demoras punitivas de juntar el caché de la CPU ponen fin a su utilidad. Los hilos son eso. –
@ Hans Passant: Esto no entiende las corutinas. Las corutinas no son un reemplazo de los hilos y no los usa para lo mismo que usaría los hilos. El objetivo es escribir código limpio y cómodo (¡no simultáneo!) En el que una llamada a función puede pausarse, de modo que pueda regresar cuando tenga más información, sin bloquear el ciclo principal. No hay sobrecarga para hacer esto, como lo hace lua. Los hilos del sistema operativo serían un mal sustituto en ese caso de uso. –