首页 > 解决方案 > 启动一个goroutine(即调用'go')会失败吗?

问题描述

执行时是否可能失败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()
}

标签: goconcurrencygoroutine

解决方案


go语句不能失败(仅在“极端”情况下,例如内存不足,但失败的go语句将是您的问题中最少的)。

当然,如果没有同步,您无法保证该 goroutine 何时运行。因此,您的示例使用sync.WaitGroup不正确,好像 goroutine 直到maingoroutine 到达时才被调度wg.Wait(),它甚至可能永远不会启动,因为当maingoroutine 结束时,您的程序也会结束。

而是在主 goroutine 中增加 WaitGroup 的计数器(最好调用WaitGroup.Done()deferred,这样即使 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 完成其工作时发生)。


推荐阅读