如何优雅的退出goroutine

来源:互联网 发布:网络主播行业分析 编辑:程序博客网 时间:2024/06/06 01:00

问题来源

项目中,同步数据的时候使用多个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一定会退出

优雅的退出goruntine

最开始的想法是,通过在外部停止的方法来停掉所有超时的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介绍

原创粉丝点击