发起goroutine(即调用“ go”)会失败吗?

时间:2019-04-08 10:06:06

标签: go concurrency goroutine

执行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()
}

1 个答案:

答案 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完成工作时才会发生)。