Muchos idiomas modernos admiten trabajar con corutinas a nivel de idioma. Actualmente, Java no admite corutinas, pero existe la esperanza de que las cosas puedan cambiar en el futuro.
En C ++ 20, se planea introducir soporte para trabajar con corutinas.
Usando JNI podemos escribir corutinas en C ++ y usar en c贸digo Java.
Consideremos qu茅 corutinas nativas se pueden escribir y c贸mo usarlas en el c贸digo Java.
El generador le permite crear una secuencia de valores de un tipo determinado, mientras que los valores se generan de forma perezosa y sincr贸nica.
generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_yield i; } }
Generator<Integer> gen1 = Coroutine.yield(5); Generator<Float> gen2 = Coroutine.yield(1f, 5); Generator<Double> gen3 = Coroutine.yield(v -> v * 2, 1d, 5); for (int item : gen1) { System.out.println("yield value: " + item); }
Asynchronous Generator le permite crear una secuencia de valores de un tipo determinado, mientras que los valores se generan de manera lenta y asincr贸nica.
async_generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_await 1s; co_yield i; } }
Generator<Integer> gen1 = Coroutine.yieldAsync(5); Generator<Float> gen2 = Coroutine.yieldAsync(1f, 5); Generator<Double> gen3 = Coroutine.yieldAsync(v -> v * 2, 1d, 5); for (int item : gen1) { System.out.println("yield value: " + item); }
La tarea realiza un c谩lculo asincr贸nico, que se realiza perezosamente, mientras que la rutina no se ejecuta hasta que la tarea se inicia expl铆citamente.
Las corutinas se pueden usar como flujos de luz. En este caso, el n煤mero de subprocesos en ejecuci贸n en el sistema puede ser limitado, por ejemplo, no m谩s de 1000. Y la rutina puede ejecutarse tanto como desee.
Al comenzar una rutina, se verifica si est谩 lista. De lo contrario, la rutina se detiene y el sistema operativo le pasa el controlador. En este punto, se ejecuta una pieza 煤til de c贸digo. Cuando la corutina est谩 lista, se realiza la renovaci贸n de la misma.
struct awaiter { bool await_ready() const { return false; } void await_resume() {} void await_suspend(std::coroutine_handle<> handler) { if (!handler.done()) { handler.resume(); } } }; co_await awaiter{};
Como cuando se inicia un hilo, puede pasar Runnable o Callable a una corutina.
Coroutine.await(() -> { int sum = 5 + 10; }); Task<Integer> task = Coroutine.await(() -> { int sum = 5 + 10; return sum; });
El temporizador detiene la tarea actual durante la duraci贸n requerida.
auto operator co_await(const std::chrono::system_clock::duration& duration) { return timer{duration}; } co_await 10ms;
Se puede usar como reemplazo de Thread.sleep ().
Coroutine.await(10, TimeUnit.MILLISECONDS);
Las corutinas tambi茅n se pueden usar para escribir c贸digo sin bloqueo para trabajar con el sistema de archivos, la red, etc.
Como puede ver, las corutinas facilitan la escritura de c贸digo asincr贸nico, permitiendo que partes del c贸digo se ejecuten sin bloquear la transmisi贸n.
Las corutinas que planean comenzar en C ++ 20 aparecer谩n como caracter铆sticas de lenguaje puro.
Se planea agregar generadores, tareas y otras rutinas al est谩ndar C ++ 23 o posterior.
Puede escribir sus propias corutinas usted mismo o usar una biblioteca preparada, por ejemplo,
cppcoro .
Los compiladores MVSC, Clang ya admiten corutinas como una extensi贸n, y GCC solo est谩 en la etapa de desarrollo.
El c贸digo fuente completo se puede ver en github:
code