1.sync.WaitGroup

package main

import (
	"fmt"
	"sync"
	"time"
)

//控制并发的方式
//多个gourouting同时做一个事情的时候,只有多个gorouting同时完成,才算完成,先做好的就是要等待其他未完成的,所有的gourouting要
//都完成,才算完成

func main() {
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		defer wg.Done()
		time.Sleep(2 * time.Second)
		fmt.Println("one finishi")
	}()

	go func() {
		defer wg.Done()
		time.Sleep(1 * time.Second)
		fmt.Println("two finishi")
	}()

	wg.Wait()
	fmt.Println("大家工作完成了,可以休息一下...")
}

2.

//业务场景:需要我们主动通知某一个gourouting结束,如我们开启一个后台gorouting一直做事,如监控
//现在不需要做事了,就是要通知这个监控gourouting结束,不然他会一直跑。
//chan+select
package main

import (
	"fmt"
	"time"
)

//业务场景:需要我们主动通知某一个gourouting结束,如我们开启一个后台gorouting一直做事,如监控
//现在不需要做事了,就是要通知这个监控gourouting结束,不然他会一直跑。
//chan+select

func main() {

	stop := make(chan bool)

	go func() {
		for {
			select {
			case <-stop:
				fmt.Println("监控退出,停止了......")
				return
			default:
				fmt.Println("监控工作中 ...")
				time.Sleep(2 * time.Second)

			}

		}

	}()

	time.Sleep(10 * time.Second)
	fmt.Println("可以了,通知监控停止。。。")
	stop <- true

	time.Sleep(5 * time.Second)
	fmt.Println("job 完成")

}

2.1

//业务场景:需要我们主动通知某一个gourouting结束,如我们开启一个后台gorouting一直做事,如监控
//现在不需要做事了,就是要通知这个监控gourouting结束,不然他会一直跑。
//context  重新写
package main

import (
	"context"
	"fmt"
	"time"
)

//业务场景:需要我们主动通知某一个gourouting结束,如我们开启一个后台gorouting一直做事,如监控
//现在不需要做事了,就是要通知这个监控gourouting结束,不然他会一直跑。
//context  重新写

func main() {

	//stop := make(chan bool)
	ctx, cancel := context.WithCancel(context.Background()) //Context跟踪gourouting

	go func(ctx context.Context) {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("监控退出,停止了......")
				return
			default:
				fmt.Println("监控工作中 ...")
				time.Sleep(2 * time.Second)

			}

		}

	}(ctx)

	time.Sleep(10 * time.Second)
	fmt.Println("可以了,通知监控停止。。。")
	cancel() //取消指令发送

	time.Sleep(5 * time.Second)
	fmt.Println("job 完成")

}

3.

//使用context控制多个gourouting,退出工作
//本例中,当我们使用cancel函数通知取消是,这三个gourouting都会结束
package main

import (
	"context"
	"fmt"
	"time"
)

//使用context控制多个gourouting,退出工作
//本例中,当我们使用cancel函数通知取消是,这三个gourouting都会结束
func main() {

	ctx, cancel := context.WithCancel(context.Background())
	go watch(ctx, "监控1")
	go watch(ctx, "监控2")
	go watch(ctx, "监控3")

	time.Sleep(10 * time.Second)
	fmt.Println("可以通知监控停止了...")
	cancel() //发布通知停止工作信息
	time.Sleep(5 * time.Second)

}

func watch(ctx context.Context, name string) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println(name, "监控退出,停止了......")
			return
		default:
			fmt.Println(name, "监控工作中 ...")
			time.Sleep(2 * time.Second)
		}
	}
}