:wave: Hello, team! I am just started reading abou...
# coroutines
r
👋 Hello, team! I am just started reading about coroutines and wonder if someone have and/or can provide diagram which shows how internal of the library works? I am interested in internals like CoroutineScheduler, EventLoop etc. And the most interested flow right now for me is: 1. creation of coroutine 2. how does it get into the scheduler queue? 3. how coroutine state is changed and by which instance 4. And how it returns to the main thread with a result? Thanks 🙂
c
The original KEEP should have all the gory details you’re looking for. It’s long and quite dense, but is a very good read for getting a better understanding of how coroutines work under the hood
d
One thing that is still hard for me to understand is: Assume you have just 2 actual threads, because you have 2 CPUs. You launch a coroutine, it gets scheduled on 1 of the threads. At what point can this coroutine get unscheduled? When somewhere along the line it calls
suspendCoroutine
? Say I'm making a blocking network call with (for sake of argument) HttpUrlConnection (on JVM version 20 so no virtual threads). Does this mean the coroutine keeps blocking the thread it is running on? Okay, in this case, since there is nothing else to be done, I assume so. But what about if 2 other coroutines want to do the same thing. Does the scheduler decide itself to suspend one of the running coroutines in favor of the new one?
x
Is you use
<http://Dispatchers.IO|Dispatchers.IO>
on a machine with 2 CPUs, you still have access to 64 threads. The Dispatchers.IO documentation says:
Copy code
It defaults to the limit of 64 threads or the number of cores (whichever is larger)
d
Well, imagine there are 65 simultaneous network calls then and 64 of them that are running are stuck waiting for network IO 🙂, would the scheduler pause one of those coroutines and put #65 on one of the threads?
x
Using the default
<http://Dispatchers.IO|Dispatchers.IO>
yes, you'd have 64 blocked threads and no more available. However, you can use the CoroutineDispatcher::limitedParallelism function to create your own dispatcher with a different number of backing threads
r
As I understood coroutines implementation support cooperative multitasking(or non-preemptive) which means several coroutines can use one thread. And as I understood correctly it done by
CoroutineScheduler
implementation.
d
Ah ok, so in theory, coroutines would alternate in getting slices of thread-CPU time in that case?
x
You're partially right @Roman Abaev. There can be more that one coroutine executing on the same thread as far as there's only suspension points and no blocking calls. @Davio was placing himself in an scenario where you have strictly blocking calls (i.e. network calls). In that case, each time a blocking call is executed, it will block the backing thread until it has a response
👍 1
d
So in that case there's never going to be a moment where the suspendable coroutine is actually suspended in favor of another coroutine that wants to run?
x
That's it, when you have a blocking call, there's no way to release or reuse the thread until that process completes
r
I think it is a little bit confusing because on the level of threads there is no coroutines and only Runnable (Task). Coroutines exist only in a user level. So coroutine will be suspended in a favor of another or maybe even more correct to say would be that coroutine will suspend itself so other coroutine can run. But it doesn’t mean that task which was created from this coroutine will be started because all threads might be busy.