63 lines
1.4 KiB
Go
63 lines
1.4 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"time"
|
||
)
|
||
|
||
// 子工作函数:监听 context 取消信号
|
||
func subWorker(ctx context.Context, id int) {
|
||
defer fmt.Printf("subWorker %d:清理完成\n", id)
|
||
|
||
for {
|
||
select {
|
||
case <-ctx.Done():
|
||
fmt.Printf("subWorker %d:收到取消信号(%v),退出\n", id, ctx.Err())
|
||
return
|
||
default:
|
||
fmt.Printf("subWorker %d:处理子任务...\n", id)
|
||
time.Sleep(300 * time.Millisecond)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 主工作函数:管理子 Goroutine
|
||
func mainWorker(ctx context.Context) {
|
||
defer fmt.Println("mainWorker:清理完成")
|
||
|
||
// 启动 2 个子 Goroutine
|
||
for i := 0; i < 2; i++ {
|
||
go subWorker(ctx, i)
|
||
}
|
||
|
||
// 主工作循环
|
||
for {
|
||
select {
|
||
case <-ctx.Done():
|
||
fmt.Printf("mainWorker:收到取消信号(%v),退出\n", ctx.Err())
|
||
return
|
||
default:
|
||
fmt.Println("mainWorker:处理主任务...")
|
||
time.Sleep(500 * time.Millisecond)
|
||
}
|
||
}
|
||
}
|
||
|
||
func main() {
|
||
// 创建可取消的 context(根上下文为 context.Background())
|
||
ctx, cancel := context.WithCancel(context.Background())
|
||
|
||
// 启动主工作 Goroutine
|
||
go mainWorker(ctx)
|
||
|
||
// 3 秒后触发取消
|
||
time.Sleep(3 * time.Second)
|
||
fmt.Println("主程序:发送取消信号")
|
||
cancel() // 触发所有基于该 context 的 Goroutine 退出
|
||
|
||
// 等待所有 Goroutine 完成清理
|
||
time.Sleep(1 * time.Second)
|
||
fmt.Println("主程序退出")
|
||
}
|