当前位置: 首页 > 面试题库 >

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

史良哲
2023-03-14
问题内容

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

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

package main

import (
    "fmt"
    "runtime"
)

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

问题答案:

这些不是线程,它们是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


 类似资料:
  • 问题内容: 据说Go的不是(请参见此处和此处)。我有兴趣找出在我忽略使用互斥锁/ etc保护访问地图的情况下可能发生的情况。 具体来说 ,是否会发生以下任何情况? 假设我有一个带有键,,…,的映射,当我要求(i!= j)时,并发问题会导致获取错误吗? 可以在应用程序中导致吗? 问题答案: 正如评论已经指出的那样,种族是不好的。与Java不同,Go具有非常弱的保证,因此, 即使不执行包含种族的代码

  • 问题内容: 如果在Travis CI上运行Golang测试,它将以三个点下载所有依赖项: 什么表示或扩展到那里?我已经做过一些研究,但这似乎不是Unix惯例。 问题答案: 从命令: 如果导入路径包含一个或多个“ …”通配符,则通配符是一种模式,每个通配符都可以匹配任何字符串,包括空字符串和包含斜杠的字符串。这样的模式将扩展到在GOPATH树中找到的所有名称与模式匹配的软件包目录。作为一种特殊情况,

  • 问题内容: 我知道前两列是什么,但是什么? 问题答案: 它称为struct标记,可以在运行时使用包对其进行解析。 来自https://golang.org/ref/spec#Struct_types: 字段声明后可以跟一个可选的字符串文字标签,该标签成为相应字段声明中所有字段的属性。 这些标记通过反射接口可见,并参与结构的类型标识,但否则将被忽略。 一些使用反射的包(例如)并使用标签来更好地处理特

  • 问题内容: 在Google I / O 2012演示文稿 Go Concurrency Patterns中 ,Rob Pike提到了多个 goroutine 可以 驻留 在一个线程中。这是否意味着它们被实现为协程?如果没有,如何实施?欢迎使用源代码链接。 问题答案: 不完全的。Go常见问题解答部分 为什么使用goroutines而不是线程? 解释: Goroutine是使并发易于使用的一部分。这个

  • 问题内容: 上面的代码创建了100个goroutine,将num插入到通道c,所以我只是想知道,这些goroutine是否会以随机顺序执行?在我的测试期间,输出将始终为1到100 问题答案: 严格来说,您观察到的“随机”行为是不确定性行为。 要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有许多goroutine试图写入通道,而只有一个goroutine从通道中读出。 阅读过程只是顺序的,

  • 问题内容: 我正在通过为GAE编写应用来学习Go,这是处理程序函数的签名: 我在这里是指针新手,那么为什么对象是指针,但不是呢?是否有必要采用这种方式,或者只是为了使某种基于高级指针的代码成为可能? 问题答案: 您得到的是指向非导出类型的指针,但与接口一样,这是不可见的。 从server.go: 另一方面,它是指向具体结构的指针,因此需要显式传递引用。 从request.go: