我想通了!這一切都在源頭上。
有一個我不知道的Linux系統調用。 它被稱爲「克隆」。它比fork更靈活,它允許子進程在其父地址空間中生存。
下面是線程創建過程的簡要概述。
首先出現的是在src/runtime/proc.go
一個newm
功能。這個 函數負責創建一個新的工作線程 (或者在註釋中調用它的機器)。
// Create a new m. It will start off with a call to fn, or else the scheduler.
// fn needs to be static and not a heap allocated closure.
// May run with m.p==nil, so write barriers are not allowed.
//go:nowritebarrier
func newm(fn func(), _p_ *p) {
// ... some code skipped ...
newosproc(mp, unsafe.Pointer(mp.g0.stack.hi))
}
該函數調用newosproc
這是OS特定的。 對於Linux,可以在src/runtime/os_linux.go
中找到。這裏 是該文件的相關部分:
var (
// ...
cloneFlags = _CLONE_VM | /* share memory */
_CLONE_FS | /* share cwd, etc */
_CLONE_FILES | /* share fd table */
_CLONE_SIGHAND | /* share sig handler table */
_CLONE_THREAD /* revisit - okay for now */
)
// May run with m.p==nil, so write barriers are not allowed.
//go:nowritebarrier
func newosproc(mp *m, stk unsafe.Pointer) {
// ... some code skipped ...
ret := clone(cloneFlags, /* ... other flags ... */)
// ... code skipped
}
而且clone
功能在特定架構的 文件中定義。對於amd64,它在src/runtime/sys_linux_amd64.s
。 這是實際的系統調用。
所以走程序並在多個OS線程使 在CPU運行的跨越,但他們使用一個共享的地址空間。
P ...我喜歡Go。
[夠程的官方文檔(https://golang.org/doc/effective_go.html#goroutines)應該是有幫助的。 – chrk
以及[本文](https://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html)。 – chrk
@chrk,問題是:不是官方文檔,也不是第二篇文章闡明瞭如何去運行時提供共享變量的同步。官方文檔指出:「一個goroutine有一個簡單的模型:它是一個在同一地址空間中與其他goroutines同時執行的函數」。但是,如果他們處於不同的進程中,他們不能處於相同的地址空間中...... – ea7ababe