Golang,重启恐慌的例程的正确方法

Sak*_*kib 8 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.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)

Ank*_*kur 8

您可以在以下函数中提取恢复逻辑:

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)


Zan*_*ynx 1

哦,我并不是说下面的方法比你的方法更正确。这只是另一种方法。

创建另一个函数,调用它printerRecover或类似的函数,然后在其中执行延迟/恢复。然后在printer循环中调用printerRecover. 添加函数返回值来检查是否需要 goroutine 由于某种原因退出。