golang--監控goroutine異常退出


在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個退出信號。由圖可以得到我們的程序運行良好。

轉貼請注明來自:格通


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM