| > Go's scheduler is a single threaded event loop No, it isn't. > like every other scheduler on the planet This is not true either. In fact it doesn't make sense. Schedulers are not single threaded event loops. The scheduler (any scheduler) is entered in various scenarios. Sometimes voluntarily, sometimes not. Sometimes the scheduler code can run concurrently, sometimes not. Sometimes the scheduler code can run in parallel, sometimes not. The Go scheduler is both concurrent and parallel. > It runs, sequentially, in different threads which makes the situation confusing I don't know what this statement means. The Go scheduler certainly runs on different threads. So what. > It's also cooperative. Actually it's not purely cooperative, it does voluntary preemption, very similar to voluntary preemption in the Linux kernel. The check happens in every function prolog. > More importantly, there's a number of simultaneous syscalls that will kill a go program. There's self-imposed user-configurable limit that defaults to 10000 threads for running system calls. The limit has nothing to do with the Go scheduler, it can be set arbitrarily high with no penalty. > It doesn't have the basic isolation that OSes provide. The most basic isolation provided by operating systems is virtual memory. Go is a shared-memory execution environment, so this doesn't apply. What other "basic isolation" is provided by operating systems that's missing from Go? |
It means that some of the data structures the scheduler examines on every run are shared data, with locking. That makes it effectively single threaded, even if it technically runs on different CPUs (at different times). Put another way it means that it'll never run faster than a single-threaded scheduler would.
> Actually it's not purely cooperative, it does voluntary preemption, very similar to voluntary preemption in the Linux kernel.
You mean preemption inside the linux kernel, in some kernel-space threads ? Because it sounds very different to preemption of applications.
> The check happens in every function prolog.
So it's cooperative. The standard that is normally used is simple : does "for {}" crash("block" if you prefer) some part of the system ? On the linux scheduler the answer is no. In Erlang the answer is no. On the Go scheduler, the answer is yes.
On the linux scheduler with proper ulimits it's bloody hard to crash the system, for instance, forkbombs, memory bombs, ... won't do it. I hope we'll get a language where you can do that too (and the JVM comes quite close to this ideal, some JVMs actually have it even).