执行go f
时是否可能失败?
由于关键字go没有返回值,如何确定高并发过程中goroutine是否成功启动?
例如:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg = &sync.WaitGroup{}
go func() { // How do I know if there is any failure here?
wg.Add(1)
fmt.Println("halo world")
wg.Done()
}()
time.Sleep(time.Nanosecond)
wg.Wait()
}
答案 0 :(得分:4)
go
语句不能失败(仅在“极端”情况下,例如内存不足,但是失败的go
语句将是最少的问题)。
当然,如果没有同步,则无法保证计划的goroutine何时运行。因此,您对sync.WaitGroup
的示例使用是不正确的,因为好像goroutine直到main
goroutine到达wg.Wait()
才被调度,它甚至可能无法启动,就像main
goroutine一样结束,您的程序也结束。
相反,应在主goroutine中增加WaitGroup的计数器(最好延迟调用WaitGroup.Done()
,因此即使goroutine出现恐慌也要调用它):
var wg = &sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("halo world")
}()
wg.Wait()
那样,您甚至不需要睡眠,wg.Wait()
将阻塞直到其他goroutine调用wg.Done()
(只有在其他goroutine完成工作时才会发生)。