Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who is responsible for suspension and continuation of coroutines?

This might be a very basic question in terms of Asynchronous Programming, but I tried reading about it and couldn't find any resource for the same.

Assumption: A general idea I have about asynchronous programming:

When we start a blocking operation(networks call, reading from DB/file), we can delegate it to Kernel thread(s) which will keep our application thread(s) free for other jobs. The kernel thread waits for the job to be done and gives a callback to the application thread whenever the job is done.

Coroutines: I have been reading about Kotlin Coroutines for last few days. I think the concept wise coroutines are language agnostic though. The question I have been getting is:

How the suspension and continuation takes place for a co-routine. Coroutines are not threads(which are given a slice of the processor by OS), they are tasks which will be scheduled on a thread to be executed.

Who keeps looking for the program in execution and say, this coroutine has hit a suspension point and it should be taken out of thread. Another coroutine which needs to be resumed from continuation should be scheduled on the thread. As for as I have read about Java Fibers it will be done by a Fiber Scheduler, is it similar in Kotlin?

Thank for the help in advance.

like image 787
Mritunjay Avatar asked May 24 '19 08:05

Mritunjay


People also ask

How coroutines are suspended?

Which coroutine gets suspended? The outer async starts a coroutine. When it calls computation() , the inner async starts a second coroutine. Then, the call to await() suspends the execution of the outer async coroutine, until the execution of the inner async 's coroutine is over.

Can coroutines be suspended and resumed?

If you notice the functions closely, they can be used to resume the coroutine with a return value or with an exception if an error had occurred while the function was suspended. This way, a function could be started, paused, and resume with the help of Continuation. We just have to use the suspend keyword.

How are coroutines implemented?

A coroutine internally uses a Continuation class to capture the contexts for its execution. Then the dynamic aspect is modeled as a Job class. The use of async usually creates a Deferred job, which is a subclass of the Job class. The CoroutineContext type is required for a coroutine to execute.

Are coroutines provide asynchronous?

They provide us with an easy way to do synchronous and asynchronous programming. Coroutines allow us to replace callbacks and build the main safety without blocking the main thread. Let's see how to do that. Note: The AsyncTask class was deprecated in Android 11.


1 Answers

Coroutine suspension is entirely explicit and first-class. It happens when you call suspendCoroutine() or suspendCancellableCoroutine(), passing in a block that receives the continuation as the parameter.

The block can do whatever it wants with the continuation object, and when someone, somewhere, calls continuation.resume(resultValue(), it will resume. The thread it resumes on is initially the thread that calls resume(), but the logic inside resume immediately delegates to the Dispatcher in charge, which then typically submits the resumption to another thread or thread pool.

The Dispatcher logic is again first-class and you can write your own dispatcher. However, this is almost never needed because there are only a handful of meaningful ways to do it, and Kotlin already supports them.

You can also review a concrete example in code that demonstrates the naked usage of suspendCoroutine and coroutine.resume(), without the layer the Dispatcher adds to it.


BTW you never delegate blocking operations to "kernel threads" to make them non-blocking. Async operations don't block any thread. On the low level there's for example the mechanism of a selector that receives events from IO operations when they complete. It works much like the event loop in a GUI thread.

like image 187
Marko Topolnik Avatar answered Oct 19 '22 01:10

Marko Topolnik