Earlier quoted context omitted.
They're not coroutines though. This is a little semantic, but a coroutine normally uses cooperative multitasking exclusively. Something like: coroutine foo while queue not full put something in queue when full yield bar coroutine bar while queue not empty take from queue do something with what was taken when empty yield foo Each time the coroutine yields, it removers it's state and execution resume another coroutine,…
You (or a language) don’t have to yield-to another coroutine. You may resume and yield-from as in: coroutine producer forever while no full packet resume recv into buffer on eof return null yield (extract packet) coroutine consumer while packet = (resume producer) if packet is null break process packet which is more like a green or lightweight thread. It means that it can be pre-emptively paused and resumed, it doesn…
In your example, it seems to still be cooperative, you simply yield to the scheduler which is itself a coroutine and will then decide what other coroutine to yield back too. Here's a naive coroutine scheduler :
ArrayList coroutines;
coroutine scheduler
for i = 0;; i = i++ % coroutines.size()
yield coroutines[i]
It's still voluntary yielding though, preemptive would be that the scheduler can at any time interupt the task, but here it can't, it will still only be possible to schedule another task ounce a yield point voluntarily yields back to the scheduler.Actually, your example is simpler then that: (resume producer) is the same as: yield producer. And the yield with a return value is the same as: yield consumer. For the latter, the language probably allows yielding to the previous coroutine under the hood or like I said maybe it yields to a scheduler.
I was also showing that you can even do something like yield to a scheduler which will then pick the next coroutine to resume, which makes it even more "thread like", but still cooperative.
The coroutine's cooperative nature has an advantage, it naturally models coordination. With a preemptive scheme like Java virtual thread, you will still have to protect shared data and have ways to coordinate and synchronize like mutex, locks and all that.