为了账号安全,请及时绑定邮箱和手机立即绑定

如何进行可重新启动、线程安全的 AfterFunc() 调用

如何进行可重新启动、线程安全的 AfterFunc() 调用

Go
慕尼黑的夜晚无繁华 2022-06-21 16:48:54
如何以线程安全的方式进行延迟的、可重新启动的函数调用?这是一个非常常见的用例,例如,如果您想对某些更改做出反应,但频率不会超过 X 毫秒一次。我能想出的代码是:var t *time.Timerfunc restartableDelayed()  {    if t != nil {        t.Stop()    }    t = time.AfterFunc(time.Second, func() {        t = nil        // ...        // Do the stuff here        // ...    })}这里明显的问题是,t = nil分配是从另一个 goroutine 调用的,而不是初始分配,这会受到竞争。如何以适当的并发安全方式完成此操作?我在这里唯一能想到的就是使用互斥锁来同步对 的访问t,但这感觉有点麻烦。还有更简洁的选择吗?
查看完整描述

1 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

我认为在这里使用互斥锁是合理的,想不出更简单的解决方案。


你只需要添加几行就可以了:


var (

    mu sync.Mutex

    t  *time.Timer

)


func restartableDelayed() {

    mu.Lock()

    defer mu.Unlock()


    if t != nil {

        t.Stop()

    }

    t = time.AfterFunc(time.Second, func() {

        mu.Lock()

        t = nil

        mu.Unlock()


        // Do the stuff here

    })

}


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信