나는 그것을 알아 냈다! 그것은 모두 출처입니다.
내가 알지 못하는 Linux 시스템 호출이 있습니다. "복제본"이라고합니다. 그것은 포크보다 융통성이 있으며, 자식 프로세스가 부모의 주소 공간에 살도록 허용합니다.
다음은 스레드 생성 프로세스에 대한 간략한 개요입니다.
먼저 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))
}
이 기능은 OS에 고유 newosproc
통화. 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
입니다. 실제 시스템 호출입니다.
그래서 Go 프로그램은 을 CPU에 걸쳐 사용할 수 있도록하는 여러 OS 스레드에서 실행되지만 하나의 공유 주소 공간을 사용합니다.
피 ... 나는 사랑합니다.
[goroutines의 공식 문서] (https://golang.org/doc/effective_go.html#goroutines)가 도움이됩니다. – chrk
[이 기사] (https://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html). – chrk
@chrk 문제는 다음과 같습니다. 공식 문서 또는 두 번째 기사가 런타임에 공유 변수의 동기화를 제공하는 방법에 대해 설명하지 않았습니다. 공식 문서에는 "goroutine은 간단한 모델을 가지고 있습니다 : 이것은 동일한 주소 공간에서 다른 goroutine과 동시에 실행되는 함수입니다". 그러나 그들은 서로 다른 프로세스에 있다면 같은 주소 공간에있을 수 없습니다. ... – ea7ababe