package main import ( "context" "fmt" "sync" "time" ) func main() { } // //例子中我们通过select判断stop是否接受到值,如果接受到值就表示可以推出停止了,如果没有接受到, //就会执行default里面的监控逻辑,继续监控,直到收到stop的通知 //以上控制goroutine的方式在大多数情况下可以满足我们的使用,但是也存在很多局限性,比如有很多goroutiine, //并且这些goroutine还衍生了其他goroutine,此时chan就比较困难解决这样的问题了 func testChan() { stop := make(chan bool) go func() { for { select { case <-stop: fmt.Println("") return default: fmt.Println("groutine监控中...") time.Sleep(1 * time.Second) } } }() time.Sleep(10 * time.Second) fmt.Println("可以了,监控停止了") stop <- true time.Sleep(5 * time.Second) } //以上例子一定要等到两个goroutine同时做完才会全部完成,这种控制并发方式尤其适用于多个goroutine协同做一件事情的时候。 func testWaitGroup() { var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() time.Sleep(2 * time.Second) }() go func() { defer wg.Done() time.Sleep(3 * time.Second) }() wg.Wait() fmt.Println("好了,大家都干完活了") } func CancelTest() { ctx, cancel := context.WithCancel(context.Background()) go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("协程退出,停止了...") return default: fmt.Println("协程运行中...") time.Sleep(2 * time.Second) } } }(ctx) time.Sleep(time.Second * 30) fmt.Println("两分钟时间到了,关闭子协程") cancel() time.Sleep(time.Second * 10) fmt.Println("演示结束") } // TimeOutTest WithTimeout func TimeOutTest() { ctx, _ := context.WithTimeout(context.Background(), time.Minute*1) go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("协程退出,停止了...") return default: fmt.Println("协程运行中...") time.Sleep(2 * time.Second) } } }(ctx) time.Sleep(time.Second * 70) fmt.Println("演示结束") } // DeadLineTest WithDeadline func DeadLineTest() { ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Minute*1)) go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("协程退出,停止了...") return default: fmt.Println("协程运行中...") time.Sleep(2 * time.Second) } } }(ctx) time.Sleep(time.Second * 70) fmt.Println("演示结束") } // WithValueTest WithCancel func WithValueTest() { ctx, cancel := context.WithCancel(context.Background()) //附加值 valueCtx := context.WithValue(ctx, "test", "子协程1") go func(ctx context.Context) { for { select { case <-ctx.Done(): //取出值 fmt.Println(ctx.Value("test"), "监控退出,停止了...") return default: //取出值 fmt.Println(ctx.Value("test"), "goroutine监控中...") time.Sleep(2 * time.Second) } } }(valueCtx) time.Sleep(10 * time.Second) fmt.Println("可以了,通知监控停止") cancel() //为了检测监控过是否停止,如果没有监控输出,就表示停止了 time.Sleep(5 * time.Second) }