简体   繁体   English

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

[英]Kill a method in an infinite loop (golang)

I am working with a piece of code that has an intentional infinite loop, I can't modify that code. 我正在处理具有故意无限循环的一段代码,但无法修改该代码。 I want to write some tests on that method (eg make sure it triggers actions at the right times) but I don't want to orphan a bunch of go routines. 我想对该方法进行一些测试(例如,确保它在正确的时间触发动作),但是我不想孤立一堆go例程。 So I am trying to find a way that I can kill/interrupt that goroutine. 因此,我试图找到一种方法可以杀死/中断该goroutine。

I was thinking of trying to wrap it in a wrapper function that would kill it after a signal. 我正在考虑尝试将其包装在一个包装函数中,该包装函数会在发出信号后将其杀死。 Like this (doesn't work). 这样(不起作用)。

func wrap(inf func()) func() {
  return func() {
    select {
    case inf():
    case <-time.After(5 * time.Second):
    }
  }
}

func main() {
  go wrap(inf())()
  // do things
}

All the variations I can think of don't really work. 我能想到的所有变化都没有用。 I was thinking of wrapping the inf in a function that writes to a channel (that will never get called), or something with a return statement. 我当时正在考虑将inf封装在一个写入通道的函数中(永远不会被调用),或者带有return语句的函数中。 And then the select can read from that. 然后select可以从中读取。 The problem is then you have to launch that. 问题是您必须启动它。 If you do it in this routine you're never getting to the select . 如果按此例程进行操作,则永远不会进入select If you do it in another routine, you've just made the problem worse. 如果您在其他例程中执行此操作,则只会使问题变得更糟。

So, is there a way that I can kill that routine? 那么,有什么方法可以杀死我的例行程序吗?

(yes - I would rather change the infinite loop code, but can't here) (是的-我宁愿更改无限循环代码,但不能在此处)

If you can't change the loop code, you can't kill the loop. 如果您无法更改循环代码,则无法终止循环。 Go is rather intentionally designed such that there's no way to kill a goroutine from outside of the goroutine, short of actually terminating the program itself. Go的设计是经过精心设计的,因此没有办法从goroutine外部杀死goroutine,除非实际终止程序本身。

If you can change the loop itself, the typical method of killing a routine is to provide a quit channel to the goroutine, and then close (or send on) that channel to tell the loop to exit. 如果您可以更改循环本身,则杀死例程的典型方法是为goroutine提供退出通道,然后关闭(或继续发送)该通道以告知循环退出。 Example: 例:

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

But without some way to coding that closure behavior into the loop itself, there's no way (to my knowledge) of specifically killing that goroutine or terminating the loop within it (unless you can trigger a panic in it, but that's a terrible way to handle that issue) 但是,如果没有某种方法将闭包行为编码到循环本身中,就我所知,就没有办法专门杀死该goroutine或终止其中的循环(除非您可以在其中触发恐慌,但这是一种可怕的处理方式)该问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM