我有以下示例代码.我想保持4个goroutines一直在运行.他们有恐慌的可能.在恐慌的情况下,我有一个恢复,我重新启动goroutine.
我实施的方式有效,但我不确定它是否是正确和正确的方法.有什么想法吗
package main
import (
"fmt"
"time"
)
var gVar string
var pCount int
func pinger(c chan int) {
for i := 0; ; i++ {
fmt.Println("adding ", i)
c <- i
}
}
func printer(id int, c chan int) {
defer func() {
if err := recover(); err != nil {
fmt.Println("HERE", id)
fmt.Println(err)
pCount++
if pCount == 5 {
panic("TOO MANY PANICS")
} else {
go printer(id, c)
}
}
}()
for {
msg := <-c
fmt.Println(id, "- ping", msg, gVar)
if msg%5 == 0 {
panic("PANIC")
}
time.Sleep(time.Second * 1)
}
}
func main() {
var c chan int = make(chan int, 2)
gVar = "Preflight"
pCount = 0
go pinger(c)
go printer(1, c)
go printer(2, c)
go printer(3, c)
go printer(4, c)
var input string
fmt.Scanln(&input)
}
Run Code Online (Sandbox Code Playgroud)
您可以在以下函数中提取恢复逻辑:
func recoverer(maxPanics, id int, f func()) {
defer func() {
if err := recover(); err != nil {
fmt.Println("HERE", id)
fmt.Println(err)
if maxPanics == 0 {
panic("TOO MANY PANICS")
} else {
go recoverer(maxPanics-1, id, f)
}
}
}()
f()
}
Run Code Online (Sandbox Code Playgroud)
然后使用它像:
go recoverer(5, 1, func() { printer(1, c) })
Run Code Online (Sandbox Code Playgroud)
哦,我并不是说下面的方法比你的方法更正确。这只是另一种方法。
创建另一个函数,调用它printerRecover或类似的函数,然后在其中执行延迟/恢复。然后在printer循环中调用printerRecover. 添加函数返回值来检查是否需要 goroutine 由于某种原因退出。