小编典典

Go程序中的三个后台goroutine是什么?

go

Go似乎总是在任何给定时间运行至少4个goroutine。不是主要goroutine的其他三个是什么?

http://play.golang.org/p/MQBiLmHXBK

package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Println(runtime.NumGoroutine()) //4
}

阅读 302

收藏
2020-07-02

共1个答案

小编典典

这些不是线程,它们是goroutine,并且数量可能会根据当前的实现而有所不同(即,在go1.2中将显示2)。

现在,看来您有1个用于main,而3个则用于runtime / gc。

import "fmt"

func main() {
    fmt.Println(func() string { panic(nil); return "" }())
}

由此可见

goroutine 16 [running]:
runtime.panic(0x0, 0x0)
    /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5
main.func·001(0x3ea4f, 0xdc4b0)
    /test/threads.go:6 +0x28
main.main()
    /test/threads.go:6 +0x1e

goroutine 17 [runnable]:
runtime.MHeap_Scavenger()
    /usr/local/go/src/pkg/runtime/mheap.c:507
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445

goroutine 18 [runnable]:
bgsweep()
    /usr/local/go/src/pkg/runtime/mgc0.c:1976
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445

goroutine 19 [runnable]:
runfinq()
    /usr/local/go/src/pkg/runtime/mgc0.c:2606
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445

如果删除fmt,并使用自举print功能,则只会得到2个goroutine。

import "runtime"

func main() {
    print(runtime.NumGoroutine(), "\n")
}

// prints 2

如果您想确切地知道正在运行的goroutine,请打印堆栈跟踪,调用panic或使用SIGQUIT终止进程(该进程将打印堆栈跟踪并退出)。如果运行绝对最小程序,则可以从中获得堆栈跟踪,可以看到2个goroutine:

package main

func main() {
    panic(nil)
}

Goroutine非常便宜, 许多
事情将启动和停止更多Goroutine,因此尝试跟踪其下限不是很有用。请注意,即使只有两个goroutines(main /
runtime.panic和runtime.MHeap_Scavenger),计数却已经达到17。

panic: nil

goroutine 16 [running]:
runtime.panic(0x0, 0x0)
    /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5
main.main()
    /test/threads.go:4 +0x28

goroutine 17 [runnable]:
runtime.MHeap_Scavenger()
    /usr/local/go/src/pkg/runtime/mheap.c:507
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445
exit status 2
2020-07-02