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 终止执行的机制。

posted @ 2023-05-27 14:10  大西瓜Paul  阅读(165)  评论(0编辑  收藏  举报
/*增加返回顶部按钮*/ 返回顶部 /*给标题增加蓝色背景长条*/