上下文
select {
case <-chan1:
...
case val := <-chan2:
...
default:
...
}package main
import (
"context"
"fmt"
"sync"
"time"
)
// doSomething 方法中会执行一个循环任务,在每个循环执行的周期内都会检查上下文状态,
// 如果上下文接收到Done信号,则终止任务
func doSomething(ctx context.Context, waitgroup *sync.WaitGroup) {
// 结束方法时释放一个协程计数器
defer func() {
waitgroup.Done()
}()
fmt.Println("start doing jobs.")
// 执行工作任务,用时6秒
for i := 0; i < 6; i++ {
// 执行任务
fmt.Printf("doing job %d\n", i)
time.Sleep(time.Second)
// 检查上下文状态,如果接收到Done信号则终止任务,否则进入下一个循环
select {
case <-ctx.Done():
fmt.Println("stop doing jobs")
return
default:
}
}
fmt.Println("finish jobs.")
}
func main() {
fmt.Println("Hello World")
// 初始化等待组,用于阻塞主方法直到所有协程执行完毕
var waitgroup sync.WaitGroup
// 添加一个协程计数器
waitgroup.Add(1)
// 首先在主方法体中通过context.Background()创建一个上下文,做为根级上下文,只用于派生子上下文,不做其他用途
// 通过根级上下文进行派生,获得一个子上下文以及子上下文的终止方法
ctx, cancel := context.WithCancel(context.Background())
// 执行协程方法,并将上下文和等待组做为参数传入,该方法运行耗时6秒
go doSomething(ctx, &waitgroup)
// 等待3秒后执行子上下文的终止方法,关闭上下文
go func() {
fmt.Println("stop doing jobs in 3 seconds")
time.Sleep(3 * time.Second)
cancel()
}()
// 阻塞主方法直到协程计数器归零
waitgroup.Wait()
fmt.Println("Finished Execution")
}
最后更新于