这篇文章深入探讨了在 Go 中高效使用计时器,并提供了在与 select 语句结合使用的时候如何避免潜在的内存泄漏问题的方法。Let’s Go !
最常见的 Timer + Select 使用方式
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
// Starting a goroutine
go func() {
for {
select {
case num := <-ch:
fmt.Println("get num is ", num)
case <-time.After(2 * time.Second):
fmt.Println("time's up!!!")
}
}
}()
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(1 * time.Second)
}
}
Go 标准库文档[1]提到,每次调用 time.After 都会创建一个新的计时器。所以我们需要考虑到一个重要的问题。
底层的计时器在计时器被触发之前不会被垃圾收集器回收。
也就是说如果这些计时器没有达到设定的时间,它们就不会被垃圾收集。这可能导致内存泄漏,特别是在经常使用计时器的长时间运行的程序中。
Timer 的最佳实践
为了更有效地管理资源并避免内存泄漏,可以使用 time.NewTimer 和 timer.Reset。这种方法允许重用相同的计时器,减少资源消耗和潜在的内存泄漏风险。
下面是使用 time.NewTimer 改进的代码示例:
//1. Define a duration for the timer.
idleDuration := 5 * time.Minute
//2. Create a new timer with the specified duration.
idleDelay := time.NewTimer(idleDuration)
//3. Ensure the timer is stopped properly to avoid resource leaks.
defer idleDelay.Stop()
//4. Enter a loop to handle incoming messages or time-based events.
for {
//5. Reset the timer to the specified duration at the beginning of each loop iteration.
idleDelay.Reset(idleDuration)
//6. Use select to wait on multiple channel operations.
select {
// Case to handle incoming messages.
case s, ok := <-in:
// Check if the channel is closed. If so, exit the loop.
if !ok {
return
}
// Process the received message `s`.
// Add relevant code here to handle the message.
// Case to handle a situation where the timer elapses.
case <-idleDelay.C:
// Increment the idle counter or handle the timeout event.
// This is typically where you'd add code to handle a timeout scenario.
idleCounter.Inc()
// Case to handle cancellation or context expiration.
case <-ctx.Done():
// Exit the loop if the context is done.
return
}
}
通过这些注释我们了解了如何使用计时器和 select 语句在并发的 Go 程序中协同工作。
Conclusion
上述的例子展示了在 Go 的并发编程中如何正确使用和管理计时器。开发者必须遵循 Go 标准库的建议,这样才能够写出更高效、可靠的代码。
pkg functions: https://pkg.go.dev/time#pkg-functions
原文始发于微信公众号(Go Official Blog):使用 Select +Timer 时如何避免内存泄露?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/269888.html