Files
the-way-to-go_ZH_CN/eBook/14.6.md
Haigang Zhou f08d76efa6 第十四章上半部分 (#836)
Co-authored-by: Joe Chen <jc@unknwon.io>
2022-05-17 16:24:13 +08:00

32 lines
1.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 14.6 协程和恢复 (recover)
一个用到 `recover()` 的程序(参见[第 13.3 节](13.3.md)停掉了服务器内部一个失败的协程而不影响其他协程的工作。
```go
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()``defer` 修饰的函数可能在调用 `recover()` 之前就调用了一个 `logging()` 函数panicking 状态不会影响 `logging()` 代码的运行。因为加入了恢复模式,函数 `do()`(以及它调用的任何东西)可以通过调用 `panic()` 来摆脱不好的情况。但是恢复是在 panicking 的协程内部的:不能被另外一个协程恢复。
## 链接
- [目录](directory.md)
- 上一节:[通道,超时和计时器](14.5.md)
- 下一节:[对比新旧模型:任务和工作](14.7.md)