Golang 并发 关闭协程
使用Context传递关闭信号
在Golang中,Context是用于控制协程退出的工具。Context可以让我们在多个goroutine之间传递取消信号,并且能够及时终止协程的执行。它非常适用于一些需要及时停止的场景,比如网络请求、任务执行等。
使用Context的基本流程如下:
- 使用context包创建一个Context对象,并返回取消函数
- 在需要控制的goroutine中,调用Context的Done方法来检查是否需要退出,如果需要退出,则退出当前goroutine
- 需要退出时,调用取消函数,通知goroutine退出
package main
import (
"context"
"fmt"
"time"
)
func longRunningTask(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("longRunningTask exit")
return
default:
// 执行一些耗时的操作
time.Sleep(1 * time.Second)
fmt.Println("longRunningTask running")
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go longRunningTask(ctx)
// 运行一段时间后停止任务
time.Sleep(5 * time.Second)
cancel()
fmt.Println("main goroutine , Before 10s , ing ...")
time.Sleep(10 * time.Second)
fmt.Println("main goroutine , After 10s , end .")
}
输出结果
longRunningTask running
longRunningTask running
longRunningTask running
longRunningTask running
main goroutine , Before 10s , ing ...
longRunningTask running
longRunningTask exit
main goroutine , After 10s , end .
在这个示例中,我们首先使用 context包
创建了一个 Context对象ctx
和一个 取消函数cancel
。
然后我们启动了一个长时间运行的任务longRunningTask,并传入了 Context对象
作为参数。
在longRunningTask中,我们通过select语句来检查是否需要退出当前goroutine。如果收到了取消信号,则输出一条消息并返回函数;否则继续执行耗时操作。
在main函数中,我们运行了一个长时间的任务,并在5秒后调用cancel函数来发送取消信号。当longRunningTask接收到取消信号后,会退出函数,并输出一条消息。最后我们等待1秒钟,让程序有足够的时间来处理各种清理工作。
Context还可以用于超时控制、请求传递等其他场景。在实际使用中,我们需要根据具体的情况来选择合适的Context对象,并根据需要传递上下文信息和取消信号。同时,也需要注意在多个goroutine之间传递Context对象时的线程安全性。
主动关闭协程运行的常见场景
1. 协程在执行一个不断重复的任务
协程在执行一个不断重复的任务时,此时协程是不会主动终止运行的。但是在某个时刻之后,不需要再继续执行该任务了,需要主动关闭goroutine的执行,释放协程的资源。