utine”的目的,笔者做了很多尝试,如
- select结构(条件实现)
- panic退出机制(失败)
- 获取pid杀死(失败)
- ptrace单步调试(失败)
- ...(失败)
利用select语句实现
关于“如何杀死goroutine”,网上有一部分答案就是利用select实现的,但是这种方式实现的代码并不适用于服务类的程序,但是对于一般非服务类程序的确能够实现杀死goroutine的效果,代码如下:
func main() {
wrapper := func() chan int {
c := make(chan int)
go func() {
HeavyWork(0)
c <- 1
}()
return c
}
select {
case <-wrapper():
case <-time.After(1 * time.Second):
fmt.Println("time limit exceed")
}
// time.Sleep(3 * time.Second)
}
但是一旦主函数没有立即退出,而是作为某种服务而继续运行时,这里删除了main函数的最后一行注释time.Sleep(3 * time.Second)
,延迟三秒后退出。可以看见尽管已经超时并输出"time limit exceed"之后,HeavyWork
在main函数没退出前依旧在运行。效果如下
所以使用select-timeout的方式比较适合实时退出类型的程序,能够实现一定程度上的并发控制,
小结
就目前而言,还没有完美的方案来解决控制goroutine的问题,事实上Go似乎并不允许和推荐人们直接控制goroutine,所以暂时还无法做到从外部直接控制goroutine的生命周期,所以比较推荐的做法还是只能通过goroutine主动退出的方法,循环监听channel,在发出退出信号后最多只消耗一轮资源后就退出,但这就要求该代码具有循环结构否则就很难使用。有更好解决方案的朋友,请务必告诉我!
转载请注明出处:http://www.cnblogs.com/tr3e/p/7995689.html