wangming1993 / issues

记录学习中的一些问题,体会与心得 https://wangming1993.github.io/issues
8 stars 4 forks source link

Difference Between Goroutines and Threads #67

Open wangming1993 opened 6 years ago

wangming1993 commented 6 years ago

In Golang Concurrency Part I, I said Goroutines are not threads. In this post I will explain the same.

Size

OS threads are basically fixed size stack, preferably 2 MB. It’s a huge space e.g. invoking 1024 threads will result in 2 GB space occupancy.

A Goroutine starts life with a small stack, typically 2 KB. Because some go routines are too small for a 2 MB stack and stack of Goroutine is growable.

The size limit for a Goroutine stack may be as much as 1GB, so thread is limited for recursive operation because recursive stack greater then 2 MB will cause, stack overflow. Go o the other hand can grow it’s stack to 1 GB, WOW, now huge recursion is possible in Go.

Scheduling

OS threads are scheduled by kernel. Hardware timer dependency.

Go run-time has its own scheduler. No hardware timer dependency. It’s a m:n scheduler. Means, m (Goroutines) => n ( Threads).

Identity

Goroutines has no identity, for some it must be an issue, but I can easily live with that. Go has this implemented because Goroutines has no TLS (Thread local storage).


Goroutines are part of making concurrency easy to use. The idea, which has been around for a while, is to multiplex independently executing functions—coroutines—onto a set of threads. When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked. The programmer sees none of this, which is the point. The result, which we call goroutines, can be very cheap: they have little overhead beyond the memory for the stack, which is just a few kilobytes.

To make the stacks small, Go's run-time uses resizable, bounded stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time grows (and shrinks) the memory for storing the stack automatically, allowing many goroutines to live in a modest amount of memory. The CPU overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.