3 ms·
async/await is really just another formulation of linked stack frames, where control is explicitly yielded. At the end of the day, the thread stack state needs
by smasher164 6y ago
async/await is really just another formulation of linked stack frames, where control is explicitly yielded. At the end of the day, the thread stack state needs to be reified somehow, and all of these approaches are equivalent in power. The only difference is that now you have a type system that delineates between functions that can and cannot be shuffled between kernel threads.
The benefits that Go (and potentially Loom) provide are with the scheduler. When Go code calls into other Go code, it's fast because preemption points can be inserted by the compiler. The goroutine is parked when it is blocked (on I/O or some foreign function), and in the slow path this logic is executed on a new kernel thread.
Although the Go approach involves more overhead in the slow path, wrangling blocking code to work with the scheduler has cross-cutting implications for library design. I.e, I don't have to worry that a library I import that does file I/O will pin my goroutine to a blocked thread by using a blocking syscall.
- jayd16 6y agoAsync/await provides a mechanism for explicit context switching between threads. This is useful when you might need to run code on specific native threads or other native tasks outside the runtime. It seems like it would be much harder or impossible in languages that work to hide these details. How do you go from implicit blocking to explicit native thread usage? At least Loom seems to be keeping native threads so Java code can simply fall back to that, I guess.
- pjmlp 6y agoYou can also use native threads in Go, by locking the current goroutine thread.
- yxhuvud 6y agoOne way to solve it is to introduce a concept like a nursery (a la structured concurrency) and when setting it up you instruct it to create a new thread that is only used for those particular tasks. This of course requires a scheduler that needs to handle hierarchical control of execution rather than having an unformed mass of tasks, but nurseries provide other benefits as well.