通过contenx关闭goroutine

// 通过 context 关闭goroutine
func ContextCancel() {
	// 创建一个通道并在 goroutine 中接收停止信号
	forever := make(chan struct{})
	// WithCancel返回一个带有Done通道的parent副本 即 cancel()
	ctx, cancel := context.WithCancel(context.Background())

	go func(ctx context.Context) {
		for {
			select {
			case <-ctx.Done(): // if cancel() execute
				forever <- struct{}{}
				return
			default:
				fmt.Println("for loop")
			}

			time.Sleep(500 * time.Millisecond)
		}
	}(ctx)

	go func() {
		time.Sleep(3 * time.Second)
		// context的Done通道在返回的cancel函数被调用时关闭
		cancel()
	}()
	// 
	<-forever
	fmt.Println("finish")
}

超时时间

func WithTimeoutContextCancel() {
	forever := make(chan struct{})
	// 超时时间
	var shortDuration = 1000 * time.Millisecond
	// context的Done通道在截止日期到期时关闭 即 ctx.Done()
	ctx, cancel := context.WithTimeout(context.Background(), shortDuration)
	// 未超时间执行完关闭
	defer cancel()
	go func(ctx context.Context) {
		for {
			select {
			case <-ctx.Done(): // if cancel() execute
				forever <- struct{}{}
				return
			default:
				fmt.Println("for loop")
			}
			//sleep 500 毫秒相对于超时时间1000毫秒 即执行了两次 for loop 结束
			time.Sleep(500 * time.Millisecond)
		}
	}(ctx)
	<-forever
	fmt.Println("finish")
}

你可能感兴趣的:(go)