如何最好地保持长时间运行的Go程序的运行?
我有一个用Go语言编写的运行时间较长的服务器。Main会触发执行程序逻辑的多个goroutine。在那之后主要没有什么用。一旦主程序退出,程序将退出。我现在使用的使程序运行的方法只是对fmt.Scanln()的简单调用。我想知道其他人如何阻止main退出。以下是一个基本示例。在这里可以使用哪些想法或最佳做法?
我考虑过创建一个通道并通过接收该通道来延迟main的退出,但是我认为如果我的所有goroutine在某个时候都处于非活动状态,可能会出现问题。
旁注:在我的服务器(不是示例)中,该程序实际上并未连接到Shell上运行,因此无论如何与控制台进行交互都没有任何意义。现在,它可以工作,但是我正在寻找“正确”的方法,假设有一种方法。
package mainimport (
    "fmt"
    "time"
)
func main() {
    go forever()
    //Keep this goroutine from exiting
    //so that the program doesn't end.
    //This is the focus of my question.
    fmt.Scanln()
}
func forever() {
    for ; ; {
    //An example goroutine that might run
    //indefinitely. In actual implementation
    //it might block on a chanel receive instead
    //of time.Sleep for example.
        fmt.Printf("%v+\n", time.Now())
        time.Sleep(time.Second)
    }
}
回答:
Go的当前运行时设计假定程序员负责检测何时终止goroutine和何时终止程序。程序员需要计算goroutine以及整个程序的终止条件。可以通过调用os.Exit或从main()函数返回以常规方式终止程序。
main()通过立即在所述通道上接收来创建通道并延迟退出,是一种防止main退出的有效方法。但是它不能解决检测何时终止程序的问题。
如果在main()函数进入等待所有goroutines终止循环之前无法计算goroutine的数量,则需要发送增量,以便main函数可以跟踪正在运行的goroutine的数量:
// Receives the change in the number of goroutinesvar goroutineDelta = make(chan int)
func main() {
    go forever()
    numGoroutines := 0
    for diff := range goroutineDelta {
        numGoroutines += diff
        if numGoroutines == 0 { os.Exit(0) }
    }
}
// Conceptual code
func forever() {
    for {
        if needToCreateANewGoroutine {
            // Make sure to do this before "go f()", not within f()
            goroutineDelta <- +1
            go f()
        }
    }
}
func f() {
    // When the termination condition for this goroutine is detected, do:
    goroutineDelta <- -1
}
另一种方法是将频道替换为sync.WaitGroup。这种方法的缺点是wg.Add(int)需要在调用之前先进行调用wg.Wait(),因此必须在其中至少创建一个goroutine,main()然后才能在程序的任何部分中创建后续goroutine:
var wg sync.WaitGroupfunc main() {
    // Create at least 1 goroutine
    wg.Add(1)
    go f()
    go forever()
    wg.Wait()
}
// Conceptual code
func forever() {
    for {
        if needToCreateANewGoroutine {
            wg.Add(1)
            go f()
        }
    }
}
func f() {
    // When the termination condition for this goroutine is detected, do:
    wg.Done()
}
以上是 如何最好地保持长时间运行的Go程序的运行? 的全部内容, 来源链接: utcz.com/qa/420584.html
