【问题标题】:Kill a method in an infinite loop (golang)在无限循环中杀死一个方法(golang)
【发布时间】:2016-10-26 03:23:29
【问题描述】:

我正在处理一段具有故意无限循环的代码,我无法修改该代码。我想对该方法编写一些测试(例如,确保它在正确的时间触发操作),但我不想孤立一堆 go 例程。因此,我正在尝试找到一种可以杀死/中断该 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 包装在一个写入通道(永远不会被调用)的函数中,或者带有返回语句的东西。然后select 可以从中读取。问题是你必须启动它。如果您在此例程中执行此操作,您将永远无法访问select。如果你在另一个例程中这样做,你只会让问题变得更糟。

那么,有什么方法可以让我终止这种例行公事吗?

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

【问题讨论】:

    标签: go infinite-loop


    【解决方案1】:

    如果你不能改变循环代码,你就不能终止循环。 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 或终止其中的循环(除非您可以在其中触发恐慌,但这是一个 可怕的方法来处理这个问题)

    【讨论】:

      猜你喜欢
      • 2011-03-30
      • 2013-08-04
      • 1970-01-01
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 2021-01-05
      • 1970-01-01
      相关资源
      最近更新 更多