init() 函数能否安全地启动 go 例程,包括 along 测试?

Can the init() function start go routines safely, including along tests?

我有一个应用程序。它创建了一个 HTTP 服务来监听我们可以用来检查应用程序状态的几个连接点。

该服务 运行 在后台运行(带有 go 例程)。

它在 init() 函数中初始化:

func init() {
    ...
    initHttpEndPoints();
    ...
}

init() 函数中创建一个 go routine 是否会导致测试此应用程序时出现问题?

我问是因为看起来我的测试重新 运行 init() 第二次,我想知道为什么会这样,副作用可能是什么......(如果所有的 go 例程突然重复,可能不太好。)

注意:完整的应用程序。在 init() 函数中创建了数百个 go 例程。我以 HTTP 端点为例。

高度相关的答案:Are tests run concurrently?

Spec: Package initialization:

Package initialization—variable initialization and the invocation of init functions—happens in a single goroutine, sequentially, one package at a time. An init function may launch other goroutines, which can run concurrently with the initialization code. However, initialization always sequences the init functions: it will not invoke the next one until the previous one has returned.

init() 函数启动 goroutines 没有错,尽管你必须记住这些 goroutines 运行 与初始化过程同时进行,所以例如你不能对初始化做任何假设(当前)包的状态。

如果您多次看到 init() 函数 运行ning,那很可能是 运行 分别进行了多次测试。 init() 函数 运行 在包的生命周期中仅运行一次。

除了 icza 的回答之外,听起来您对 testing 包的 init() 使用不正确。

与其使用 init() 来初始化测试所需的东西,不如定义函数 TestMain().