剑痴乎

剑痴乎
代码为剑,如痴如醉
  1. 首页
  2. golang
  3. 正文

Forward :How Goroutines Work

2018年1月24日 1502点热度 0人点赞 0条评论

Goroutines and Threads - the differences

Go uses goroutines while a language like Java uses threads. What are the differences between the two? We need to look at 3 factors - memory consumption, setup and teardown and switching time.

Memory consumption

The creation of a goroutine does not require much memory - only 2kB of stack space. They grow by allocating and freeing heap storage as required.[2][3] Threads on the other hand start out at 1Mb (500 times more), along with a region of memory called a guard page that acts as a guard between one thread’s memory and another.[7]

A server handling incoming requests can therefore create one goroutine per request without a problem, but one thread per request will eventually lead to the dreaded OutOfMemoryError. This isn’t limited to Java - any language that uses OS threads as the primary means of concurrency will face this issue.

Setup and teardown costs

Threads have significant setup and teardown costs because it has to request resources from the OS and return it once its done. The workaround to this problem is to maintain a pool of threads. In contrast, goroutines are created and destroyed by the runtime and those operations are pretty cheap. The language doesn’t support manual management of goroutines.

Switching costs

When a thread blocks, another has to be scheduled in its place. Threads are scheduled preemptively, and during a thread switch, the scheduler needs to save/restore ALL registers, that is, 16 general purpose registers, PC (Program Counter), SP (Stack Pointer), segment registers, 16 XMM registers, FP coprocessor state, 16 AVX registers, all MSRs etc. This is quite significant when there is rapid switching between threads.

Goroutines are scheduled cooperatively and when a switch occurs, only 3 registers need to be saved/restored - Program Counter, Stack Pointer and DX. The cost is much lower.

As discussed earlier, the number of goroutines is generally much higher, but that doesn’t make a difference to switching time for two reasons. Only runnable goroutines are considered, blocked ones aren’t. Also, modern schedulers are O(1) complexity, meaning switching time is not affected by the number of choices (threads or goroutines).[5]

How goroutines are executed

As mentioned earlier, the runtime manages the goroutines throughout from creation to scheduling to teardown. The runtime is allocated a few threads on which all the goroutines are multiplexed. At any point of time, each thread will be executing one goroutine. If that goroutine is blocked, then it will be swapped out for another goroutine that will execute on that thread instead.[6]

As the goroutines are scheduled cooperatively, a goroutine that loops continuously can starve other goroutines on the same thread. In Go 1.2, this problem is somewhat alleviated by occasionally invoking the Go scheduler when entering a function, so a loop that includes a non-inlined function call can be prempted.

Goroutines blocking

Goroutines are cheap and do not cause the thread on which they are multiplexed to block if they are blocked on

  • network input
  • sleeping
  • channel operations or
  • blocking on primitives in the sync package.

Even if tens of thousands of goroutines have been spawned, it’s not a waste of system resources if most of them are blocked on one of these since the runtime schedules another goroutine instead.

In simple terms, goroutines are a lightweight abstraction over threads. A Go programmer does not deal with threads, and similarly the OS is not aware of the existence of goroutines. From the OS’s perspective, a Go program will behave like an event-driven C program. [5]

Threads and processors

Although you cannot directly control the number of threads that the runtime will create, it is possible to set the number of processor cores used by the program. This is done by setting the variable GOMAXPROCS with a call to runtime.GOMAXPROCS(n). Increasing the number of cores may not necessarily improve the performance of your program, depending on its design. The profiling tools can be used to find the ideal number of cores for your program.

Closing thoughts

As with other languages, it is important to prevent simultaneous access of shared resources by more than one goroutine. It is best to transfer data between goroutines using channels, ie, do not communicate by sharing memory; instead, share memory by communicating.

Lastly, I’d strongly recommend you check out Communicating Sequential Processes by C. A. R. Hoare. This man was truly a genius. In this paper (published 1978) he predicted how the single core performance of processors would eventually plateau and chip-makers would instead increase the number of cores. His proposal to exploit this had a deep influence on the design of Go.

Footnotes

  • 1 - Concurrency is not parallelism by Rob Pike
  • 2 - Effective Go: Goroutines
  • 3 - Goroutine stack size was decreased from 8kB to 2kB in Go 1.4.
  • 4 - Goroutine stacks became contiguous in Go 1.3
  • 5 - Dmitry Vyukov explains scheduling of goroutines on golang-nuts
  • 6 - Analysis of the Go runtime scheduler by Deshpande et al.
  • 7 - 5 things that make Go fast by Dave Cheney
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
标签: golang
最后更新:2018年1月24日

Jeff

管理员——代码为剑,如痴如醉

打赏 点赞

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

版权声明

为支持原创,创作更好的文章,未经许可,禁止任何形式的转载与抄袭,如需转载请邮件私信!本人保留所有法定权利。违者必究!

文章目录
  • Goroutines and Threads - the differences
  • How goroutines are executed
  • Goroutines blocking
  • Threads and processors
  • Closing thoughts
  • Footnotes
最近评论
ztt 发布于 3 周前(04月05日) 你好,想看里面的视频和图片为什么没有显示呢?需要下flash吗还是什么。
huowa222 发布于 4 周前(03月26日) 同问
邱国禄 发布于 2 个月前(02月17日) Receive Delta以0.25ms为单位,reference time以64ms为单位,kDe...
啊非 发布于 4 个月前(12月30日) 大神,请教一个问题: constexpr int kBaseScaleFactor = Tran...
啊非 发布于 4 个月前(12月30日) reference time:3字节,表示参考时间,以64ms为单位,但是 代码里面是 Trans...

COPYRIGHT © 2024 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang