package main
import (
"context"
"fmt"
"sync"
"time"
)
func worker(cancelCtx context.Context, ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println(fmt.Sprintf("context value: %v", cancelCtx.Value("key1")))
for {
select {
case val := <-ch:
fmt.Println(fmt.Sprintf("read from ch value: %d", val))
case <-cancelCtx.Done():
fmt.Println("worker is cancelled")
return
}
}
}
func testTask(done chan struct{}) {
time.Sleep(time.Second * 2)
done <- struct{}{}
}
func done(cancelCtx context.Context) {
flag := make(chan struct{})
go testTask(flag)
select {
case <-flag:
fmt.Printf("done")
case <-cancelCtx.Done():
fmt.Println("worker is cancelled")
return
case <-time.After(time.Second * 3):
fmt.Println("timeout")
return
}
}
func main() {
rootCtx := context.Background()
childCtx := context.WithValue(rootCtx, "key1", "value1")
cancelCtx, cancelFunc := context.WithCancel(childCtx)
ch := make(chan int)
// 同步等待子协程处理完成通过sync.WaitGroup
wg := &sync.WaitGroup{}
wg.Add(1)
go worker(cancelCtx, ch, wg)
for i := 0; i < 10; i++ {
ch <- i
}
cancelFunc()
wg.Wait()
done(context.Background())
close(ch)
}
golang 控制子协程的退出(启用新协程)
最新推荐文章于 2023-05-20 23:51:28 发布