Golang,重新开始一个惊慌失措的程序的正确方法

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

我有以下示例代码。我想保持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)
}
主程序包
进口(
“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)
...
}