停止 time.NewTimer 在 for 循环内初始化
Stop time.NewTimer initialized inside for loop
我有一个类似于以下程序的程序:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
timeout := time.NewTimer(getTimeoutDuration())
defer timeout.Stop()
select {
case s := <-ch:
fmt.Println(s)
return
case <-timeout.C:
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}
在这种情况下停止 timeout
计时器的最佳方法是什么?
我知道上面不是推荐的方法,因为在 for 循环中使用 defer 是一种不好的做法。另一种方法是在 for 循环中使用 time.After
而不是 time.NewTimer
,因为我们不必停止 time.After
。但是如果函数在计时器触发之前退出,time.After
会导致资源泄漏(Source)。
如果你使用上下文而不是计时器,where cancel 仅在退出函数 case 条件时调用。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
ctx, cancel := context.WithTimeout(context.Background(), getTimeoutDuration())
select {
case s := <-ch:
cancel()
fmt.Println(s)
return
case <-ctx.Done():
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}
我有一个类似于以下程序的程序:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
timeout := time.NewTimer(getTimeoutDuration())
defer timeout.Stop()
select {
case s := <-ch:
fmt.Println(s)
return
case <-timeout.C:
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}
在这种情况下停止 timeout
计时器的最佳方法是什么?
我知道上面不是推荐的方法,因为在 for 循环中使用 defer 是一种不好的做法。另一种方法是在 for 循环中使用 time.After
而不是 time.NewTimer
,因为我们不必停止 time.After
。但是如果函数在计时器触发之前退出,time.After
会导致资源泄漏(Source)。
如果你使用上下文而不是计时器,where cancel 仅在退出函数 case 条件时调用。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
ctx, cancel := context.WithTimeout(context.Background(), getTimeoutDuration())
select {
case s := <-ch:
cancel()
fmt.Println(s)
return
case <-ctx.Done():
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}