Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

On the "Goroutines are not threads" slide, it says, "When a goroutine blocks, that THREAD blocks but no other goroutine blocks."

I hope that's a typo. A thread is blocked when a goroutine blocks would exhaust the worker thread pool pretty fast. Can an GO expert clarify on that?



I think the point he's trying to make is that if you make a blocking system call, it blocks the thread that goroutine is scheduled within, but other goroutines will not be blocked by this and will continue to execute.

This is not the case with many other (single-threaded) systems built exclusively around a god-loop that schedules coroutines. One coroutine making a blocking system call gums up the whole works.


Goroutines are threads though (in the sense of preemtively scheduled concurrent execution sharing memory), they just aren't OS threads.


But they aren't "preemptively scheduled concurrent execution sharing memory".

They are "cooperatively scheduled concurrent execution sharing memory".


The current implementations are cooperatively scheduled, but nothing in the specification prevents a preemptively scheduled implementation. After all, gccgo had a preemptively scheduled implementation until a few months ago.

That being said, I prefer my goroutines to be cooperatively scheduled.


When Go was first presented Rob said the term "Goroutine" was introduced precisely to avoid this kind of confusions, but old habits are hard to kill and seems that even Rob himself still falls into this trap from time to time :)


No, he didn't. It's not a typo. :-)


Similar/analogous (I believe these all have significant differences)to F# MailboxProcessor, akka actors, erlang/BEAM processes and userspace/green threads in e.g. GHC,


But the title of the slide said, "Goroutines are not threads."

I understand what you meant, but it's kind of confusing to use the same term for different things within the same slide while claiming they are different.


Yes, that is a typo. Goroutines are multiplexed to OS threads, but this is done transparently, you don't have to worry about it.

You can have tens of thousands of Goroutines without any problems.


No, that is not a typo. A goroutine that blocks by making the thread it's currently running in block in the kernel is blocking that thread too; it must since the kernel needs some context for the on-going operation. What he's saying is that the pool of other threads used by the scheduler can continue to run other goroutines, just not the one that's blocked. No typo.


But _how_ does this actually happen?

I have seen this same idea ("goroutines are very light and multiplexed into OS threads, don't worry about it") stated often, but I do not understand it, and I have not found any place where the implementation of this is actually discussed, do you have any pointers?


The post you're replying to is wrong, it's not a typo; see my reply to it.

For a background in the CSP languages have a browse of Russ Cox's http://swtch.com/~rsc/thread/ The reference [4] to Squeak is broken, it's now at http://research.microsoft.com/pubs/67508/squeak.pdf and well worth a read.

For the general case, not Go specific, there's a scheduler that tracks what processes (in the CSP sense, e.g. goroutine) are waiting on what channels. Whenever a channel becomes ready, e.g. something is available to read from it, one of the processes waiting to read from it is non-deterministically (that's important) chosen and control (the CPU's program counter, still in user-space) jumps to where it returns from the `read'. It then has the CPU all to itself until it gives control back to the scheduler by needing another particular channel-state. I'm omitting sleeping, etc., for simplicity. The switching of control is all in user-space so quite lightweight.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: