Golang,重新开始一个惊慌失措的程序的正确方法
我有以下示例代码。我想保持4个goroutines始终运行。他们有可能惊慌失措。在恐慌的情况下,我有一个恢复,我重新启动goroutine 我实施的方式是有效的,但我不确定这是否是正确和正确的方式。有什么想法吗Golang,重新开始一个惊慌失措的程序的正确方法,go,Go,我有以下示例代码。我想保持4个goroutines始终运行。他们有可能惊慌失措。在恐慌的情况下,我有一个恢复,我重新启动goroutine 我实施的方式是有效的,但我不确定这是否是正确和正确的方式。有什么想法吗 package main import ( "fmt" "time" ) var gVar string var pCount int func pinger(c chan int) { for i := 0; ; i++ { fmt.Pri
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)
}
主程序包
进口(
“fmt”
“时间”
)
var gVar字符串
var pCount int
func pinger(c chan int){
对于i:=0;;i++{
fmt.Println(“添加”,i)
哦,我不是说下面的方法比你的方法更正确。这只是另一种方法
创建另一个函数,调用它printerRecover
或类似的函数,并在其中执行延迟/恢复。然后在printer
中,只需循环调用printerRecover
。添加函数返回值以检查是否出于某种原因需要退出goroutine。like的回答,我想分享另一种方法来实现do it(尽管它与OP的方式非常相似。)我使用了一个额外的缓冲通道ch
。当goroutine陷入恐慌时,goroutine中的恢复函数将其标识I
发送到ch
。在main()底部的for循环中
,它通过从ch
接收值来检测哪个goroutine处于紧急状态以及是否重新启动
主程序包
进口(
“fmt”
“时间”
)
func main(){
var pCount int
ch:=制造(成交量,5)
f:=func(i int){
延迟函数(){
如果错误:=recover();错误!=nil{
ch您可以在以下函数中提取恢复逻辑:
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()
}
然后像这样使用它:
go recoverer(5, 1, func() { printer(1, c) })
您实现的方式是正确的。就我而言,始终保持4个例程运行的方法看起来没有多大用处,要么处理例程的ID,要么延迟生成,这可能会由于关闭而导致不可预测的堆栈。我认为您无法有效地平衡资源。您为什么不喜欢简单地生成worker需要的时候
func main() {
...
go func(tasks chan int){ //multiplexer
for {
task = <-tasks //when needed
go printer(task) //just spawns handler
}
}(ch)
...
}
func main(){
...
go func(任务chan int){//多路复用器
为了{
task=我尝试了这个方法,它只是不断地添加。你如何限制goroutine的数量?它产生goroutine,这是主要的problem@Sakib您可以执行如下操作:func main(){…for i:=0;idefer
?如果是,那么我认为我们不需要在另一个go例程中重新运行该函数,对吗?```}否则{go recoverer(maxPanics-1,id,f)}```只想确保我们在失败的情况下不会以“例程的例程”结束。谢谢
func main() {
...
go func(tasks chan int){ //multiplexer
for {
task = <-tasks //when needed
go printer(task) //just spawns handler
}
}(ch)
...
}