golang goroutine 生命期管理 标准库的 context 包来通知工作协程退出的方式
package main
import (
"context"
"fmt"
"time"
)
func longtimeCostFunc(ctx context.Context, c chan <- int) {
for i := 0; i < 10; i++ {
select{
case <-ctx.Done():
fmt.Println("calculate interrupted")
return
case <-time.After(time.Second):
fmt.Println("calcalating.....")
}
}
c <- 1
fmt.Println("calculate finished")
}
func main() {
result := make(chan int, 1)
ctx, cancel := context.WithCancel(context.Background())
go longtimeCostFunc(ctx, result)
select {
case r := <-result:
fmt.Println("lontimeCostFunc return:", r)
case <- time.After(3 * time.Second):
cancel()
fmt.Println("too long to wait for the result")
}
time.Sleep(time.Minute)
return
}
调用者通过
context.WithCancel()
获取一个可以取消的 context 及与之关联的取消函数 cancel
,然后将获取的 context 传递给工作协程(一般作为第一个参数),工作协程通过 context.Done()
监听此 context 是否已经取消,当监听到取消事件后,工作协程就可以不再继续正常的业务流程可以退出了。当调用者调用取消函数 cancel
时,所有通过 context.Done()
监听此 context 是否取消的工作协程都会收到取消的信号。使用这种方式来管理子协程的生命期的时候,要注意子协程在执行正常的业务流程中要能及时响应 context 已取消的信号context 机制除了可以用来管理协程生命期外,还可以用来在有创建关系的一组协程中共享变量。通过这个特性可以实现类似其他语言的但 golang 没有的线程本地存储特性
small_lei_it 技术无止境,追求更高。