.
- goroutines , , - , , .
, , . goroutine , goroutines .
, - ..
context.Context, , sync.WaitGroup, , goroutines . :
func main() {
all := &sync.WaitGroup{}
rootCtx, rootCancel := context.WithCancel(context.Background())
all.Add(1)
go level1(rootCtx, all)
go func() {
time.Sleep(time.Second * 3)
rootCancel()
}()
all.Wait()
}
func level1(parent context.Context, all *sync.WaitGroup) {
defer all.Done()
l1Ctx, l1Cancel := context.WithCancel(parent)
defer l1Cancel()
for i := 0; i < 3; i++ {
all.Add(1)
go level2(l1Ctx, all)
}
for {
select {
case <-parent.Done():
return
case <-time.After(time.Second):
log.Println(`level1`)
}
}
}
func level2(parent context.Context, all *sync.WaitGroup) {
defer all.Done()
for {
select {
case <-parent.Done():
return
case <-time.After(time.Second):
log.Println(`level2`)
}
}
}
, :
[ info ] level2
[ info ] level2
[ info ] level2
[ info ] level1
[ info ] level2
[ info ] level1
[ info ] level2
[ info ] level2
There is currently no official package that provides functionality that integrates context.Contextand sync.WaitGroup. The closest thing is errgroupthat may resemble this functionality with some hacks.
source
share