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 修飾的代碼可以調用那些自身可以使用 panicrecover 避免失敗的庫例程(庫函數)。舉例,safelyDo()deffer 修飾的函數可能在調用 recover 之前就調用了一個 logging 函數,panicking 狀態不會影響 logging 代碼的運行。因爲加入了恢復模式,函數 do(以及它調用的任何東西)可以通過調用 panic 來擺脫不好的情況。但是恢復是在 panicking 的協程內部的:不能被另外一個協程恢復。

鏈接

results matching ""

    No results matching ""