aitgroup wg.Add(1) go say("Hey")
输出结果如下
There
Hey
There
Hey
There
Hey
Hi
Hi
Hi
4. Defer
defer statement will defer running the function until the end of the surrounding function, either that the function is done, or if the function does happened error panic out, the defer statement will run. defer 遵循先进后出原则, 所以是倒叙执行 在上面的例子中, 我们看到 wg.Done() 函数是写在 for 循环后面的, 那么如果前面执行中如果出了错误, 程序就永远无法执行到 wg.Done() 函数, 那么整个程序就会无限制地等下去, 对于这个问题, 我们可以把 wg.Done() 函数写在 defer 语句后面, 而且放在函数的最前面,这样不管后面的执行是正常返回, 还是报错, 都会最终执行到 wg.Done() 函数. 这样才能正常向下执行.
func say(s string) {
5. panic 和 recover
func cleanUp() { defer wg.Done() if r := recover(); r != nil { fmt.Println("Recover from cleanUp:", r) } } func say(s string) { defer cleanUp() for i := 0; i<3; i++ { fmt.Println(s) time.Sleep(time.Millisecond*100) if i == 1 { panic("oh my god") } } } func main() {
运行结果, 可以看到由于在 i=1 的时候, 运行 panic()函数, 所以只能循环两次, for 循环遇到 panic 就会停止执行, 然后运行被 defer 的 cleanUp()函数, 在这个函数里, 调用了 recover()函数, 调用 recover 函数, 就会得到 panic()函数的返回值, 我们将此值赋值给了变量 r, 当 r 不等于 nil 的时候, 打印它. 最后再执行被 defer 的 wg.Done() 函数, 告知程序向下执行.
There
Hey
There
Hey
Recover from cleanUp: oh my god
Recover from cleanUp: oh my god
this is something
Hi
Hi
Recover from cleanUp: oh my god
6. Channel
package main import ( "fmt" "sync" ) var wg sync.WaitGroup
|