【问题标题】:Can initiating a goroutine (i.e. calling 'go') fail?启动一个 goroutine(即调用“go”)会失败吗?
【发布时间】:2019-04-08 10:06:05
【问题描述】:

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

【问题讨论】:

  • 如果主程序没有失败,每个 goroutine 都会运行
  • "我怎么知道这里有没有失败?"一点也不。无法启动 goroutine 的情况非常极端,以至于您无法再做任何事情。即使有迹象表明此go 失败,您也无法以任何明智的方式对该信息做出反应。
  • 我也是这么认为的,谢谢你解答我的疑惑。

标签: go concurrency goroutine


【解决方案1】:

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

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

而是在主 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 完成工作时发生)。

【讨论】:

  • 哇~,谢谢你的回答。看了很多博客都没有找到答案,现在明白了。
猜你喜欢
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2015-03-02
  • 2013-08-06
  • 1970-01-01
  • 2012-09-16
  • 2013-11-13
  • 1970-01-01
相关资源
最近更新 更多