記錄一下,方便後續寫代碼直接使用。
須要注意幾點:編程
在工做中遇到過,因爲panic 日誌打印不統一在panic監控出現漏報狀況。
經過封裝panic判斷函數,統一日誌打印,方便監控添加,避免漏報狀況。json
package main import ( "fmt" "runtime/debug" "sync" "time" ) func COMMON_PANIC_CAPTURE(panicErr interface{}) (bool){ //封裝一個panic判斷/日誌打印函數 if panicErr != nil { fmt.Printf("PANIC err:%v, stack:%s\n", panicErr, debug.Stack()) return true } return false } func main() { var wg sync.WaitGroup for i := 0; i < 3; i=i+1 { go func(x int){ //啓動go時, 須要注意參數傳遞 wg.Add(1) defer func() { wg.Done() COMMON_PANIC_CAPTURE(recover()) }() if x == 2 { panic(fmt.Sprintf("val:%d", x)) } }(i) } wg.Wait() //等待go結束 time.Sleep(2 * time.Second) //等待go panic日誌打印 fmt.Printf("end ok!\n") }
併發寫map panic, 程序沒法捕獲,多是go設計的一個問題。併發
package main import ( "fmt" "sync" "encoding/json" ) func main() { res := make(map[string]string) var wg sync.WaitGroup //group, 內部使用atomic實現計數 var mylock sync.Mutex for i := 0; i < 4000; i++ { wg.Add(1) go func(par int){ defer func() { wg.Done() }() //time.Sleep(3 * time.Second) tmp := fmt.Sprintf("%d", par %7) mylock.Lock() //加鎖 defer mylock.Unlock() //defer確保解鎖 res[tmp] = tmp }(i) } wg.Wait() resByte, _ := json.Marshal(res) fmt.Printf("%s\n", string(resByte)) }