14.6 協程和恢復(recover)
一個用到 recover
的程序(參見第 13.3 節)停掉了服務器內部一個失敗的協程而不影響其他協程的工作。
func server(workChan <-chan *Work) {
for work := range workChan {
go safelyDo(work) // start the goroutine for that work
}
}
func safelyDo(work *Work) {
defer func {
if err := recover(); err != nil {
log.Printf("Work failed with %s in %v", err, work)
}
}()
do(work)
}
上邊的代碼,如果 do(work)
發生 panic,錯誤會被記錄且協程會退出並釋放,而其他協程不受影響。
因爲 recover
總是返回 nil
,除非直接在 defer
修飾的函數中調用,defer
修飾的代碼可以調用那些自身可以使用 panic
和 recover
避免失敗的庫例程(庫函數)。舉例,safelyDo()
中 deffer
修飾的函數可能在調用 recover
之前就調用了一個 logging
函數,panicking
狀態不會影響 logging
代碼的運行。因爲加入了恢復模式,函數 do
(以及它調用的任何東西)可以通過調用 panic
來擺脫不好的情況。但是恢復是在 panicking
的協程內部的:不能被另外一個協程恢復。
鏈接
- 目錄
- 上一節:通道,超時和計時器
- 下一節:對比新舊模型:任務和工作