doulangxun7769 2014-02-18 02:01
浏览 156
已采纳

我可以强制终止goroutine而不必等待它返回吗?

Let me use an example:

func WaitForStringOrTimeout() (string, error) {
  my_channel := make(chan string)
  go WaitForString(my_channel)

  select {
  case found_string := <-my_channel:
    return found_string, nil
  case  <-time.After(15 * time.Minute):
    return nil, errors.New("Timed out waiting for string")
  }
}

In this simple example, I have some function WaitForString which blocks for awhile and eventually may return a string. I want to wrap WaitForString with this code which either returns the same string or times out with an error.

If a string is found quickly, is there still a goroutine running with a 15 minute sleep statement somewhere or is this garbage collected somehow?

If the timeout occurs and a string is never found, is there still a goroutine running WaitForString, even though there are no other routines that could observe it's output? What if WaitForString allocates a lot of memory but never returns?

Is there some way I can make WaitForString() become aware of the timeout occurring and give up?

  • 写回答

1条回答 默认 最新

  • dongtuliao6760 2014-02-18 11:21
    关注

    In general, no there isn't a way to stop another goroutine. There is a runtime.Goexit function that can be used to cause the current goroutine to exit (even if called from a deep call frame), but nothing to cause other goroutines to exit.

    For the specific case of the time module, there isn't a separate goroutine handling each timer or ticker: instead, timers are centrally managed by the runtime so it can tell when it next needs to wake up.

    While there's no goroutine hanging around, the channel and a small bookkeeping struct will stick around for the 15 minutes.

    If this is a problem, consider using time.NewTimer instead of time.After, and manually stop the timer when you return. For example:

    t := time.NewTimer(15 * time.Minute)
    defer t.Stop()
    select {
    case found_string := <-my_channel:
        return found_string, nil
    case  <-t.C:
        return nil, errors.New("Timed out waiting for string")
    }
    

    time.After is really useful for exact periodic behaviour, whereas time.NewTimer works fine for simple timeouts.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?