var timer *time.Timer
func A() {
timer.Stop() // cancel old timer
go B() // new timer
}
func B() {
timer = time.NewTimer(100 * time.Millisecond)
select {
case <- timer.C:
// do something for timeout, like change state
}
}
Run Code Online (Sandbox Code Playgroud)
函数A和B都在不同的goroutine中。
假设A在RPC goroutine中。当应用程序收到RPC请求时,它将取消B中的旧计时器,并在另一个goroutine中启动新计时器。
医生说:
停止不会关闭通道,以防止错误地从通道读取数据。
那么如何打破B中的选择以避免goroutine泄漏呢?
使用附加的独立消除信号。由于您已经有一条select语句,因此显然可以选择另一个渠道:
import "time"
var timer *time.Timer
var canceled = make(chan struct{})
func A() {
// cancel all current Bs
select {
case canceled <- struct{}{}:
default:
}
timer.Stop()
go B() // new timer
}
func B() {
timer = time.NewTimer(100 * time.Millisecond)
select {
case <-timer.C:
// do something for timeout, like change state
case <-canceled:
// timer aborted
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,所有As和B争夺计时器值。使用上面的代码,没有必要使A停止计时器,因此您不需要全局计时器,从而消除了竞争:
import "time"
var canceled = make(chan struct{})
func A() {
// cancel all current Bs
select {
case canceled <- struct{}{}:
default:
}
go B()
}
func B() {
select {
case <-time.After(100 * time.Millisecond):
// do something for timeout, like change state
case <-canceled:
// aborted
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3204 次 |
| 最近记录: |