父協程退出 子協程退出
package main
import (
"context"
"fmt"
"time"
)
func main() {
// 父context(利用根context得到)
ctx, cancel := context.WithCancel(context.Background())
// 父context的子協程
go watch1(ctx)
// 父context的子協程
go watch3(ctx)
// 父context的子協程
go watch4(ctx)
// 子context,注意:這裏雖然也返回了cancel的函數對象,但是未使用
valueCtx, _ := context.WithCancel(ctx)
// 子context的子協程
go watch2(valueCtx)
fmt.Println("現在開始等待3秒,time=", time.Now().Unix())
time.Sleep(3 * time.Second)
// 調用cancel()
fmt.Println("等待3秒結束,調用cancel()函數")
cancel()
// 再等待5秒看輸出,可以發現父context的子協程和子context的子協程都會被結束掉
time.Sleep(5 * time.Second)
fmt.Println("最終結束,time=", time.Now().Unix())
}
// 父context的協程
func watch1(ctx context.Context) {
for {
select {
case <-ctx.Done(): //取出值即說明是結束信號
fmt.Println("收到信號,父context的協程退出,time=", time.Now().Unix())
return
default:
fmt.Println("父context的協程監控中,time=", time.Now().Unix())
time.Sleep(1 * time.Second)
}
}
}
// 父context的協程
func watch3(ctx context.Context) {
for {
select {
case <-ctx.Done(): //取出值即說明是結束信號
fmt.Println("收到信號,父context的協程3退出,time=", time.Now().Unix())
return
default:
fmt.Println("父context的協程3監控中,time=", time.Now().Unix())
time.Sleep(1 * time.Second)
}
}
}
// 父context的協程
func watch4(ctx context.Context) {
for {
select {
case <-ctx.Done(): //取出值即說明是結束信號
fmt.Println("收到信號,父context的協程4退出,time=", time.Now().Unix())
return
default:
fmt.Println("父context的協程4監控中,time=", time.Now().Unix())
time.Sleep(1 * time.Second)
}
}
}
// 子context的協程
func watch2(ctx context.Context) {
for {
select {
case <-ctx.Done(): //取出值即說明是結束信號
fmt.Println("收到信號,子context的協程退出,time=", time.Now().Unix())
return
default:
fmt.Println("子context的協程監控中,time=", time.Now().Unix())
time.Sleep(1 * time.Second)
}
}
}