目前的需求是这样的
func main() {
errg := new(errgroup.Group)
errg.Go(func() error {
return test1()
})
errg.Go(func() error {
return test2()
})
if err := errg.Wait(); err != nil {
log.Error(err)
}
}
func test1() error {
return nil
}
func test2() error {
return errors.New("test2 err")
}
我如何控制 go 中的协程 有一个错误,其他 go 协程就不会执行? 同时大家如何控制超时的那? 希望能给个范例
1
anyxchachapoly 2021-09-01 10:57:30 +08:00
1. 其他 goroutine 就『不会执行』,还是『停止执行』,这是两件事,如果是前者,那就是 sequential 设计,如果后者,还得考量你 gorotuine 中的具体业务,部分情况可以简单使用 context ( chan )检测。
2. 超时如果不会自己设计,那就走 context 方式,如果要采用 timer 务必检查是否 drain 掉 C |
2
anyxchachapoly 2021-09-01 11:00:13 +08:00
我上面的回答已经相当简陋,顶多是个思路指引,但对于有基础的人而言,我相信很好理解,并且也有诸多设计可以 implement
但我看了一下你的 v2 过往问题,感觉你 go 基础得好好学,别一下蹦个高楼。 |
3
caiych 2021-09-01 11:10:21 +08:00
|
4
anyxchachapoly 2021-09-01 11:12:18 +08:00
|
5
anyxchachapoly 2021-09-01 11:13:05 +08:00
|
6
keepeye 2021-09-01 11:13:49 +08:00
需要用到 context 包,比如你想要一个 5 秒钟超时还没执行的 goroutine 自动退出,首先初始化一个 ctx
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 再改造下匿名函数 err.Go(func() error { select { case <ctx.Done(): return errors.New("中止了") default: err := test1() if err != nil { cancel() return err } else { return nil } } }) |
7
darrh00 2021-09-01 11:15:53 +08:00 via iPhone
|
8
caiych 2021-09-01 11:17:58 +08:00
@anyxchachapoly errgroup 在 Google 里也算是最佳实践:-) 是当时 go-library team 觉得非常好用才开源出来的
|
9
lasuar 2021-09-01 12:03:09 +08:00
超时控制 context 就足够了。不会玩?
简单来说 for-select + ctx.Done(),这种方式在各种库里面是遍地开花。 多说一句,开发者不能没有侵入性的中止一个协程,都是必须在协程内监听 ctx 来自行中止的。 |