加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang--监控goroutine异常退出

发布时间:2020-12-16 18:34:26 所属栏目:大数据 来源:网络整理
导读:在golang中,我们可以很轻易产生数以万计的goroutine,不过这也带来了麻烦:在运行中某一个goroutine异常退出,怎么办? 在erlang中,有link原语,2个进程可以链接在一起,一个在异常退出的时候,向另一个进程呼喊崩溃的原因,然后由另一个进程处理这些信号

在golang中,我们可以很轻易产生数以万计的goroutine,不过这也带来了麻烦:在运行中某一个goroutine异常退出,怎么办?

在erlang中,有link原语,2个进程可以链接在一起,一个在异常退出的时候,向另一个进程呼喊崩溃的原因,然后由另一个进程处理这些信号,包括是否重启这个进程。在这方面,erlang的确做得很好,估计以后这个特性会在golang中得到实现。

由此得到启发,我写了一个简单的程序,监控goroutine异常退出。

package main import ( "log"
    "runtime"
    "math/rand"
    "time" ) type message struct { normal bool //true means exit normal,otherwise
    state map[string]interface{} //goroutine state
} func main() { runtime.GOMAXPROCS(runtime.NumCPU()) mess := make(chan message,10) for i := 0; i < 100; i++ { go worker(mess) } supervisor(mess) } func worker(mess chan message) { defer func() { exit_message := message{state:make(map[string] interface{})} i := recover() if i != nil { exit_message.normal = false } else { exit_message.normal = true } mess <- exit_message }() now := time.Now() seed := now.UnixNano() rand.Seed(seed) num := rand.Int63() if num % 2 != 0 { panic("not evening") } else { runtime.Goexit() } } func supervisor(mess chan message) { for i := 0; i < 100; i++ { m := <- mess switch m.normal { case true : log.Println("exit normal,nothing serious!") case false: log.Println("exit abnormal,something went wrong") } } }

原本是想把goroutine异常退出时的状态,也就是某些变量保存到message中的state,然后在另一个goroutine里面处理这些数据,不过能力有限,暂时做不出来,以后会完善的。这里只验证goroutine在异常退出的时候,向另一个goroutine发送信号。

在worker函数里面,会判断随机数是不是偶数,不是的话会使用panic异常退出,然后使用defer向supervisor发送信号,supervisor接受到就输出结果。

下面看一下效果:

我们用了100个goroutine,也就有100个退出信号。由图可以得到我们的程序运行良好。

转贴请注明来自:格通

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读