Gre*_*ble 5 concurrency select garbage-collection go goroutine
让我举一个例子:
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")
}
}
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中,我有一些函数WaitForString,它会阻塞一段时间并最终返回一个字符串.我想用这个代码包装WaitForString,该代码返回相同的字符串或超时并带有错误.
如果快速找到一个字符串,是否还有一个goroutine在某处运行15分钟的睡眠声明,或者这个垃圾是以某种方式收集的?
如果发生超时并且从未找到字符串,那么仍然存在运行WaitForString的goroutine,即使没有其他例程可以观察它的输出吗?如果WaitForString分配了大量内存但从不返回怎么办?
有没有什么方法可以让WaitForString()意识到超时发生并放弃?
一般来说,没有办法阻止另一个 goroutine。有一个runtime.Goexit函数可用于导致当前 goroutine 退出(即使是从深度调用框架调用),但无法导致其他 goroutine 退出。
对于模块的特定情况time,没有单独的 goroutine 处理每个计时器或计时器:相反,计时器由运行时集中管理,因此它可以知道下次何时需要唤醒。
虽然没有 goroutine 闲逛,但通道和一个小型簿记结构将保留 15 分钟。
如果这是一个问题,请考虑使用time.NewTimer代替time.After,并在返回时手动停止计时器。例如:
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")
}
Run Code Online (Sandbox Code Playgroud)
time.After对于精确的周期性行为确实很有用,而time.NewTimer对于简单的超时则效果很好。