Digging Into Go Routines

April 16, 2019
Go

用了也有一段时间了。最大的感受还是在于大家对于Routine这个黑魔法的称赞1 2。不过也的确有不少反对的声音1

仅仅只是会用是不行的,那样只能是一个 “调包侠”,连开 “面试 JVM,上岗 JSP” 这种玩笑的资格都没有。

(因为打算讲的可能比较多,这篇应该也是持续更新系列)

模型

Go 使用的是一种类似于 Green Thread 的模式,在 userspace 由 Runtime 管理的Routine3。或者换一种更精确的说法,M:N plus M, P, G 的模型3

…….represents an OS thread. It's the thread of execution managed by the OS and works pretty much like your standard POSIX thread. In the runtime code, it's called M for machine.

…….represents a context for scheduling. You can look at it as a localized version of the scheduler which runs Go code on a single thread. It's the important part that lets us go from a N:1 scheduler to a M:N scheduler. In the runtime code, it's called P for processor.

…….represents a goroutine. It includes the stack, the instruction pointer and other information important for scheduling goroutines, like any channel it might be blocked on. In the runtime code, it's called a G.

简要概括就是:

以及之前文章中提到过的1

When a Go program executes what looks like a blocking I/O operation, the Go runtime actually suspends the goroutine and resumes it when an event indicates that some result is available. In the meantime other goroutines have been scheduled for execution. We therefore have the scalability benefits of asynchronous programming with a synchronous programming model.

Syscall

啧,还记得当初刚在操作系统中学了这玩意儿之后,马上就是 Meltdown and Spectre 的发现。估计乱序处理器可真是让 NSA 乐坏了。

扯远了

那么,如果按照第一小节中的模型,如何进行 syscall?还有为什么我们需要 P?3

You might wonder now, why have contexts at all? Can't we just put the runqueues on the threads and get rid of contexts? Not really. The reason we have contexts is so that we can hand them off to other threads if the running thread needs to block for some reason.

An example of when we need to block, is when we call into a syscall. Since a thread cannot both be executing code and be blocked on a syscall, we need to hand off the context so it can keep scheduling.

这篇的引用来源中有图片。如果英文无障碍的话,还是建议去读原文。(感觉我又是在搞翻译了👀)

To Be Continued3245671

Special Thanks

Why is a Goroutine’s stack infinite ?

Debugging performance issues in Go programs


  1. Go: the Good, the Bad and the Ugly ↩︎

  2. Golang 弹幕服务器优化之一 调度器 ↩︎

  3. The Go scheduler ↩︎

  4. Golang Buffer Pool Gotcha ↩︎

  5. How Stacks are Handled in Go ↩︎

  6. Contiguous stacks, Changing segmented stacks to contiguous stacks ↩︎

  7. A complete journey with Goroutines ↩︎

尝试构建简易 Event Bus

April 12, 2019
Go

Go's Slice Tricks

December 28, 2018
Go

Golang 的 GOPATH

November 25, 2018
Go
comments powered by Disqus.
Can't load? Check your connectivity and try again.