package goConcurrency import ( "context" "fmt" "strings" "sync" "time" ) func ContextCancelDeep() { // 1. 创建层级关系的cancelCtx //ctxOne, _ := context.WithCancel(context.Background()) //ctxTwo, cancel := context.WithCancel(ctxOne) //ctxThree, _ := context.WithCancel(ctxOne) //ctxFour, _ := context.WithCancel(ctxTwo) // 定时器方式保证取消 ctxOne, _ := context.WithTimeout(context.Background(), 1*time.Second) ctxTwo, cancel := context.WithTimeout(ctxOne, 1*time.Second) ctxThree, _ := context.WithTimeout(ctxOne, 1*time.Second) ctxFour, _ := context.WithTimeout(ctxTwo, 1*time.Second) wg := sync.WaitGroup{} // 2. 使用gorutine来接收ctx.Done() wg.Add(4) go func(c context.Context) { defer wg.Done() select { case <-c.Done(): // ctxOne fmt.Println("one cancel") } }(ctxOne) go func(c context.Context) { defer wg.Done() select { case <-c.Done(): // ctxTwo fmt.Println("two cancel") } }(ctxTwo) go func(c context.Context) { defer wg.Done() select { case <-c.Done(): // ctxThree fmt.Println("three cancel") } }(ctxThree) go func(c context.Context) { defer wg.Done() select { case <-c.Done(): // ctxFour fmt.Println("four cancel") } }(ctxFour) // 主动取消 cancel() wg.Wait() } func ContextCancelTime() { // 1. 创建带有时间的cancelContext //ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // deadline //ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second)) //curr := time.Now() //ctx, cancel := context.WithDeadline(context.Background(), time.Date(curr.Year(), curr.Month(), curr.Day(), 20, 30, 0, 0, time.Local)) wg := sync.WaitGroup{} wg.Add(4) // 2. 启动goroutine,携带cancelCtx for i := 0; i < 4; i++ { // 启动goroutine,携带ctx参数 go func(c context.Context, n int) { defer wg.Done() // 监听context的取消完成channel,来确定是否执行了主动cancel操作 for { select { // 等待接收c.Done()这个channel case <-c.Done(): fmt.Println("Cancel") return default: } fmt.Println(strings.Repeat(" ", n), n) time.Sleep(300 * time.Millisecond) } }(ctx, i) } // 3. 主动取消 cancel() 和到时取消 select { // 4s后主动取消 cancel() case <-time.NewTimer(4 * time.Second).C: cancel() // ctx.Done() <- time.Now fmt.Println("call cancel() Cancel") case <-ctx.Done(): // 2s后到时取消 fmt.Println("main Cancel") } wg.Wait() } func ContextCancel() { // 1. 创建cancelContext ctx, cancel := context.WithCancel(context.Background()) wg := sync.WaitGroup{} wg.Add(4) // 2. 启动goroutine,携带cancelCtx for i := 0; i < 4; i++ { // 启动goroutine,携带ctx参数 go func(c context.Context, n int) { defer wg.Done() // 监听context的取消完成channel,来确定是否执行了主动cancel操作 for { select { // 等待接收c.Done()这个channel case <-c.Done(): fmt.Println("Cancel") return default: } fmt.Println(strings.Repeat(" ", n), n) time.Sleep(300 * time.Millisecond) } }(ctx, i) } // 3. 主动取消 cancel() // 3s后取消 select { case <-time.NewTimer(2 * time.Second).C: cancel() // ctx.Done() <- time.Now } select { case <-ctx.Done(): fmt.Println("main Cancel") } wg.Wait() } type MyContextKey string func ContextValue() { wg := sync.WaitGroup{} // 1. 创建带有value的Context ctx := context.WithValue(context.Background(), MyContextKey("title"), "Go of MSB") // 2. 将ctx传递到goroutine中,使用 wg.Add(1) go func(c context.Context) { defer wg.Done() // 获取key对应的value if v := c.Value(MyContextKey("title")); v != nil { fmt.Println("Found value: ", v) return } fmt.Println("Key not found:", MyContextKey("title")) }(ctx) wg.Wait() } func ContextValueDeep() { wg := sync.WaitGroup{} // 1. 创建带有value的Context ctxOne := context.WithValue(context.Background(), "title", "Go of One") //ctxTwo := context.WithValue(ctxOne, "title", "Go of Two") ctxTwo := context.WithValue(ctxOne, "key", "Go of Two") //ctxThree := context.WithValue(ctxTwo, "title", "Go of Three") ctxThree := context.WithValue(ctxTwo, "key", "Go of Three") // 2. 将ctx传递到goroutine中,使用 wg.Add(1) go func(c context.Context) { defer wg.Done() // 获取key对应的value if v := c.Value("title"); v != nil { fmt.Println("Found value: ", v) return } fmt.Println("Key not found:", "title") }(ctxThree) wg.Wait() }