dongnao2582
2019-03-28 14:54
浏览 31
已采纳

停止时进入计时器死锁

I am trying to reuse timers by stopping and resetting them. I am following the pattern provided by the documentation. Here is a simple example which can be run in go playground that demonstrates the issue I am experiencing.

Is there a correct way to stop and reset a timer that doesn't involve deadlock or race conditions? I am aware that using a select with default involves a race condition on channel message delivery timing and cannot be depended on.

package main

import (
    "fmt"
    "time"
    "sync"
)

func main() {
    fmt.Println("Hello, playground")

    timer := time.NewTimer(1 * time.Second)
    wg := &sync.WaitGroup{}
    wg.Add(1)

    go func(_wg *sync.WaitGroup) {
        <- timer.C
        fmt.Println("Timer done")
        _wg.Done()
    }(wg)

    wg.Wait()
    fmt.Println("Checking timer")
    if !timer.Stop() {
        <- timer.C
    }

    fmt.Println("Done")
}
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongweihuai5601 2019-03-28 15:02
    已采纳

    According to the timer.Stop docs, there is a caveat for draining the channel:

    assuming the program has not received from t.C already ...

    This cannot be done concurrent to other receives from the Timer's channel.

    Since the channel has already been drained - and will never fire again, the second <-timer.C will block forever.

    打赏 评论

相关推荐 更多相似问题