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!")
}

posted on   进击的davis  阅读(43)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2021-06-28 git拉取特定分支

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示