问题来源
项目中,同步数据的时候使用多个goroutine来对一组数据进行同步请求,同步采用http的方式,所有的数据同步完成需要一个整体的响应时间,在响应时间内goroutine按照正常的结果来处理,如果超过了响应时间那么对于还没有处理完的goroutine则认为是数据同步异常。
golang中判断超时的处理办法
在golang中通过channel来对程序的超时进行判断。
- main方法通过select的方式来接收c1中的信息。如果select接收到了time.After发来的结果,那么判断程序运行的具体内容已经超过1s,则goruntine超时。
//举个例子
func main(){
c1 := make(chan string, 1)
defer close(c1)
go func(){
//需要运行的具体内容
c1 <- "result"
}()
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout 1")
}
}
- 这里的超时判断使用了channel,context包也是通过chanel来对超时进行通知,不过有更丰富的操作。
- 但是注意到,虽然main方法得到了goruntine超时的信息,但是goruntine并没有停止。如果阻塞的goruntine没有得到及时的处理,那么goruntine会越来越多。需要一种方式来让goruntine停下来。
- 值得注意的一点:goruntine的退出是不会随着调用其的方法退出的,但如果主程序退出了,那么goruntine一定会退出
【如何优雅的退出goroutine】最开始的想法是,通过在外部停止的方法来停掉所有超时的goruntine。
- 对于golang,这种方法是其不推荐的,同时也是很危险的。关于goid的内容how to get goid这里有解释
- 优雅的退出goruntine的方法是,严格的掌握控制每一个goruntine的运行时间(对于向上透明的方法,更应该了解其超时机制来避免运行超时的产生)。对于遇到的http这种同步这种问题,则需要对请求超时进行设置。
- 当你开始一个goruntine的时候,一定要知道goruntine会在何时停止。
针对“从外部结束一个 goroutine”的分析
end a blocked goroutine from outside
in golang, does it make sense to write non-blocking code?
What happens when a goroutine blocks
why 1000 goroutine generats 1000 os threads
知乎goruntine介绍
推荐阅读
- 【golang】leetcode中级-字母异位词分组&无重复字符的最长子串
- 彻底理解Golang Map
- kratos线上开源年会它来啦~
- 深入浅出 Golang 资源嵌入方案(go-bindata篇)
- 深入浅出 Golang 资源嵌入方案(前篇)
- golang 经典案例总结
- Go实战 | 基于有向无环图的并发执行流的实现
- Golang 数组和切片
- Go JSON编码与解码()
- golang map基础知识