Go | 停止 Goroutine 有几种方法
Go | 停止 Goroutine 有几种方法
1、通过共享变量实现停止信号
可以使用一个共享的布尔变量或通道来传递停止信号给 Goroutine。Goroutine可以周期性地检查这个变量或通道,如果接收到停止信号,就主动终止执行。
例子:
package main
import (
"fmt"
"sync"
"time"
)
var stopSignal bool
func myGoroutine(wg *sync.WaitGroup) {
defer wg.Done()
for {
// 执行任务
fmt.Println("hahah beibei")
time.Sleep(time.Second * 1)
if stopSignal {
fmt.Println("接收到停止该goroutine信号")
break
}
}
return
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go myGoroutine(&wg)
time.Sleep(3 * time.Second)
// 停止Goroutine
stopSignal = true
wg.Wait()
}
2、使用带缓冲通道来传递停止信号
创建一个带缓冲的通道,通过向通道发送一个特定的停止信号来通知 Goroutine
终止执行。Goroutine 可以通过接收通道中的值来判断是否要停止执行。
var stopChan = make(chan bool, 1)
func myGoroutine2(wg *sync.WaitGroup) {
defer wg.Done()
for {
// 执行任务
fmt.Println("hahah2 beibei2")
time.Sleep(time.Second * 1)
select {
case <-stopChan:
fmt.Println("接收到停止该goroutine信号")
return
default:
// 继续执行任务
fmt.Println("继续执行任务")
}
}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go myGoroutine2(&wg)
time.Sleep(3 * time.Second)
// 停止Goroutine
stopChan <- true
wg.Wait()
}
3、使用 context.Context 实现停止信号
context 包提供了一种用于跟踪 Goroutine 生命周期和传递取消信号的机制。可以使用 context.WithCancel 创建一个带有取消函数的上下文,然后在 Goroutine 中通过检查 ctx.Done() 的返回值来判断是否要停止执行。
func myGoroitine3ByContext(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
for {
// 执行任务
fmt.Println("hahah3 beibei3")
time.Sleep(time.Second * 1)
select {
case <-ctx.Done():
fmt.Println("接收到停止该goroutine信号", ctx.Err())
return
default:
// 继续执行任务
fmt.Println("继续执行任务")
}
}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancel(context.Background())
go myGoroitine3ByContext(ctx, &wg)
time.Sleep(3 * time.Second)
// 停止Goroutine
cancel() // 调用取消函数,取消上下文
wg.Wait()
}
请注意,以上方法只能向 Goroutine 发送停止信号,真正的终止或回收 Goroutine 是由 Go 运行时自动处理的。因此,停止信号只是一种请求 Goroutine 终止执行的机制。