golang 中四种结束子协程的方法
在 golang 中,怎样更好的控制子协程的退出呢,这里说说可用的几种方法:
- channel
- context
- sync.WaitGroup
- runtime.GoExit()
具体见测试代码:
package main import ( "context" "log" "math" "math/rand" "runtime" "sync" "testing" "time" ) func TestChanClose(t *testing.T) { ch := make(chan struct{}) go func() { for { select { case <- ch: log.Println("Channel closed, and now exit.") return default: log.Println("Exec task...") time.Sleep(500 * time.Millisecond) } } }() log.Println("Main thread handle...") time.Sleep(3 * time.Second) ch <- struct{}{} log.Println("Main thread done!") } func TestCtxTimeout(t *testing.T) { ctx := context.Background() ctx, _ = context.WithTimeout(ctx, 3*time.Second) go func() { for { select { case <- ctx.Done(): log.Println("Recv ctx timeout signal, exit.") return default: log.Println("Exec task...") time.Sleep(500 * time.Millisecond) } } }() log.Println("Main thread handle...") time.Sleep(4 * time.Second) log.Println("Main thread done!") } func TestWaitGroup(t *testing.T) { var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() for i := 0; i < 5; i++ { log.Println("Exec task...") time.Sleep(500 * time.Millisecond) } }() wg.Wait() log.Println("Main thread done!") } func TestGoExit(t *testing.T) { log.Println("Main thread begin!") rand.Seed(time.Now().UnixNano()) max := math.MaxInt32 go func() { for { num := rand.Intn(max) result := num % 9 == 0 switch result { case true: log.Println("Exit Num:", num) log.Println("Sub thread exit.") runtime.Goexit() default: time.Sleep(100 * time.Microsecond) log.Println("Num:", num) } } }() time.Sleep(10 * time.Second) log.Println("Main thread done!") }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-06-28 git拉取特定分支