go goroutine 怎樣進行錯誤處理
前言
在 Go 語言程序開發(fā)中,goroutine 的使用是比較頻繁的,因此在日常編碼的時候 goroutine 里的錯誤處理,怎么做會比較好呢?
一般我們的業(yè)務代碼如下:
func main() { var wg sync.WaitGroup wg.Add(2) go func() { //... 業(yè)務邏輯 wg.Done() }() go func() { //... 業(yè)務邏輯 wg.Done() }() wg.Wait() }
在上面的代碼中,我們運行了多個 goroutine,每個協(xié)程又是單獨行動的,想要拋出 error 錯誤信息,也不怎么明智。
通過錯誤日志記錄
常用的第一種方法:通過把錯誤記錄寫入到日志文件中,再結(jié)合相關的 logtail 進行采集和梳理。
但這又會引入新的問題,那就是調(diào)用錯誤日志的方法寫的到處都是,代碼結(jié)構(gòu)也比較亂、不直觀。
最重要的是無法針對 error 做特定的邏輯處理和流轉(zhuǎn)。
利用 channel 傳輸
大家可能會想到 Go 的經(jīng)典哲學:不要通過共享內(nèi)存來通信,而是通過通信來實現(xiàn)內(nèi)存共享(Do not communicate by sharing memory; instead, share memory by communicating)。
第二種方法:利用 channel 來傳輸多個 goroutine 中的 errors:
func main() { cherrors := make(chan error) wgDone := make(chan bool) var wg sync.WaitGroup wg.Add(2) go func() { //... 業(yè)務邏輯 wg.Done() }() go func() { //... 業(yè)務邏輯 err := returnErr() if err != nil { cherrors <- err } wg.Done() }() go func() { wg.Wait() close(wgDone) }() select { case <-wgDone: break case err := <-cherrors: close(cherrors) fmt.Println(err) } time.Sleep(time.Second) } func returnErr() error { return errors.New("出錯啦。。我是錯誤信息") }
雖然使用 channel 后已經(jīng)方便了不少,但編寫 channel 還要關心一些非業(yè)務向的邏輯。
使用 sync/errgroup
第三種方法,就是使用官方提供的 golang.org/x/sync/errgroup
標準庫:
type Group func WithContext(ctx context.Context) (*Group, context.Context) func (g *Group) Go(f func() error) func (g *Group) Wait() error
- Go:啟動一個協(xié)程,在新的 goroutine 中調(diào)用給定的函數(shù)。
- Wait:等待協(xié)程結(jié)束,直到 Go 方法中的所有函數(shù)調(diào)用都返回,然后返回其中第一個非零錯誤(如果有錯誤的話)。
結(jié)合其特性能夠非常便捷的針對多 goroutine 進行錯誤處理:
func main() { group := new(errgroup.Group) nums := []int{-1, 0, 1} for _, num := range nums { num := num group.Go(func() error { res, err := output(num) fmt.Println(res) return err }) } if err := group.Wait(); err != nil { fmt.Println("Get errors: ", err) } else { fmt.Println("Get all num successfully!") } } func output(num int) (int, error) { if num < 0 { return 0, errors.New("math: square root error!") } return num, nil }
每啟動一個新的 goroutine 都直接使用 Group.Go
方法,在等待和錯誤處理上使用 Group.Wait
方法。
這種方法進行錯誤處理的好處是不需要關注非業(yè)務邏輯的控制代碼,比較簡潔明了。
總結(jié)
在 Go 語言中,goroutine 是一種常用的方法,為此我們需要更了解 goroutine 的一系列相關知識,像是 context、error處理等
在團隊開發(fā)中,統(tǒng)一一定的規(guī)范,這樣的代碼閱讀起來就會比較明朗,一些隱藏很深的 Bug 也會減少很多。
到此這篇關于go goroutine 怎樣進行錯誤處理的文章就介紹到這了,更多相關go goroutine 錯誤處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Air實現(xiàn)Go程序?qū)崟r熱重載使用過程解析示例
這篇文章主要為大家介紹了Air實現(xiàn)Go程序?qū)崟r熱重載使用過程解析示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04golang跳轉(zhuǎn)語句goto,break,continue的使用及區(qū)別說明
這篇文章主要介紹了golang跳轉(zhuǎn)語句goto,break,continue的使用及區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12