【Go】如何终止goroutine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var wg sync.WaitGroup func foo(){ defer wg.Done() for { fmt.Println( "我是foo函数内的Print" ) time.Sleep(time.Millisecond*500) } } func main() { wg.Add(1) go foo() wg.Wait() } |
以上代码永远不会退出,那么如何来通知子goroutine退出呢?
一、可以添加一个标记值
// 添加tag标记值 var wg sync.WaitGroup var tag bool // 标记值 func foo(){ defer wg.Done() for { fmt.Println("我是foo函数内的Print") time.Sleep(time.Millisecond*500) if tag { // tag为真退出foo fmt.Printf("foo停止啦") break } } } func tagFunc(tag *bool){ time.Sleep(time.Second*10) *tag = true // 将tag设为真 } func main() { wg.Add(1) go foo() go tagFunc(&tag) wg.Wait() }
二、channel传值
var wg sync.WaitGroup var tag = make(chan bool,1) // 初始化tag channel func foo(){ defer wg.Done() FOO://for循环标签 for { fmt.Println("我是foo函数内的Print") time.Sleep(time.Millisecond*500) select { case <- tag: fmt.Println("foo停止啦") close(tag) break FOO // 跳出for虚幻 default: } } } func tagFunc(){ time.Sleep(time.Second*10) tag <- true // 向通道传值 wg.Done() } func main() { wg.Add(2) go foo() go tagFunc() wg.Wait() }
三、context(官方推荐)
// 原理与第二种类似 var wg sync.WaitGroup func foo2(ctx context.Context) { defer wg.Done() FOO2: for { fmt.Println("我是foo2函数内的Print") time.Sleep(time.Millisecond * 500) select { case <-ctx.Done():// 有值执行退出 fmt.Println("foo2停止啦") break FOO2 default:// 无值继续循环 } } } func foo(ctx context.Context) { defer wg.Done() wg.Add(1) go foo2(ctx) // 将ctx传递给子goroutine FOO: for { fmt.Println("我是foo函数内的Print") time.Sleep(time.Millisecond * 500) select { case <-ctx.Done(): // 有值执行退出 fmt.Println("foo停止啦") break FOO default: // 无值继续循环 } } } func tagFunc(cancel context.CancelFunc) { time.Sleep(time.Second * 10) cancel() //运行cancelFunc wg.Done() } func main() { // ctx可用于goroutine之间传递,当执行cancelFunc时,ctx.Done()传入空的chan结构体 ctx, cancelFunc := context.WithCancel(context.Background()) wg.Add(2) go foo(ctx) go tagFunc(cancelFunc) wg.Wait() }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?