在无限循环中杀死一个方法(golang)

时间:2016-06-23 16:56:56

标签: go infinite-loop

我正在使用一段有意无限循环的代码,我无法修改该代码。我想对该方法进行一些测试(例如,确保它在正确的时间触发操作),但我不想孤立一堆例程。所以我试图找到一种方法,我可以杀死/打断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。如果你在另一个例行程序中这样做,你就会让问题变得更糟。

那么,有没有办法可以杀死那个例程?

(是的 - 我宁愿改变无限循环代码,但不能在这里)

1 个答案:

答案 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>糟糕的处理该问题的方法)