mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-19 17:49:02 +08:00
30 lines
1.5 KiB
Markdown
30 lines
1.5 KiB
Markdown
# 14.6 协程和恢复(recover)
|
||
|
||
一个用到`recover`的程序(参见章节13.3)停掉了服务器内部一个失败的协程而不影响其他协程的工作。
|
||
```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()`中`deffer`修饰的函数可能在调用`recover`之前就调用了一个`logging`函数,`panicking`状态不会影响`logging`代码的运行。因为加入了恢复模式,函数`do`(以及它调用的任何东西)可以通过调用`panic`来摆脱不好的情况。但是恢复是在`panicking`的协程内部的:不能被另外一个协程恢复。更多深入的细节处理可以在[http://www.tideland.biz/SupervisingGoroutines](http://www.tideland.biz/SupervisingGoroutines)(ref.43)找到。
|
||
|
||
|
||
## 链接
|
||
|
||
- [目录](directory.md)
|
||
- 上一节:[通道,超时和计时器](14.5.md)
|
||
- 下一节:[对比新旧模型:任务和工作](14.7.md)
|