我正在使用一段有意无限循环的代码,我无法修改该代码。我想对该方法进行一些测试(例如,确保它在正确的时间触发操作),但我不想孤立一堆例程。所以我试图找到一种方法,我可以杀死/打断goroutine。
我正在考虑将其包装在一个包装函数中,该函数会在信号之后将其删除。像这样(没有工作)。
func wrap(inf func()) func() {
return func() {
select {
case inf():
case <-time.After(5 * time.Second):
}
}
}
func main() {
go wrap(inf())()
// do things
}
我能想到的所有变化都无法发挥作用。我想将inf
包装在一个写入通道的函数中(永远不会被调用),或者带有return语句的东西。然后select
可以从中读取。问题是你必须启动它。如果你在这个例程中这样做,你就永远不会进入select
。如果你在另一个例行程序中这样做,你就会让问题变得更糟。
那么,有没有办法可以杀死那个例程?
(是的 - 我宁愿改变无限循环代码,但不能在这里)
答案 0 :(得分:3)
如果无法更改循环代码,则无法终止循环。 Go是有意设计的,因此没有办法从goroutine外部杀死goroutine,而不是实际终止程序本身。
如果你可以改变循环本身,杀死例程的典型方法是为goroutine提供一个退出通道,然后关闭(或发送)该通道以告诉循环退出。例如:
quitCh := make(chan struct{})
go func() {
for {
select {
case <-quitCh:
return
// other cases to handle what you need to do
}
}
}()
// Once you're done
close(quitCh) // goroutine exits
但是如果没有某种方法将闭包行为编码到循环本身中,那么(据我所知)没有办法专门杀死goroutine或终止循环(除非你可以触发它的恐慌,但那是一个< em>糟糕的处理该问题的方法)