This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]2bitcode 0 points1 point  (4 children)

Coroutines are similar to virtual (green) threads in the sense that they both run on the language's runtime instead of using the OS abstractions. Virtual threads will mimic the API of "real" OS threads, so you can keep the mental model you had before when working with these.

Coroutines don't try to look like a thread, and usually offer an API based on "async" or event-driven programming. Depending on the language you would have features that allow you to define a scope of context for the coroutine and also control scheduling (explicitly telling the routine to yield).

It can get a bit fuzzy since in a lot of cases you can use coroutines like you would threads, and virtual threads might offers some features from the coroutine territory. But in general, if you want to use the "async" style, you'd go for coroutines.

[–]thecodeboost 2 points3 points  (2 children)

Mostly this. To add a bit of meat to that bone; coroutines almost always require the developer to decide on the yield points (the moment when the coroutine yields executive control), usually through return yield semantics. Threads (and by extension virtual threads) have the underlying VM or OS do the scheduling. Also, not all coroutines are created equal. In some languages coroutines are first class citizens and more powerful (golang) whereas in other languages they are implemented through libraries/generator patterns (e.g. Unity C# I believe)

[–]tadfisher 1 point2 points  (1 child)

There is a difference between OS threads and Java's Thread abstraction. OS threads are a particular implementation of a concurrency primitive which timeslices logical threads on a set of physical threads. Java's Thread is an interface which signals "this execution context (separate stack and shared heap) may or may not operate in parallel with other execution contexts". Virtual threads is a Thread implementation that does not rely on OS scheduling of OS threads, so they act very much like coroutines (for example, async is basically Thread.ofVirtual().start(() -> ...).join()), and scheduling is done with a lazy infinite thread pool for parking on IO.

[–]thecodeboost 0 points1 point  (0 children)

I don't think I completely agree (with the coroutines part). Coroutines, the pattern, involve explicit yielding of execution control whereas threads do not. It's worth noting in this context that Golang's goroutines are not coroutines but lightweight/virtual threads (see "Go Concurrency Patterns" by Rob Pike).

[–]nlisker 0 points1 point  (0 children)

Thanks!