登录
首页 >  Golang >  Go问答

执行可重启和线程安全的 AfterFunc() 调用的最佳方式

来源:stackoverflow

时间:2024-03-11 12:27:28 386浏览 收藏

golang学习网今天将给大家带来《执行可重启和线程安全的 AfterFunc() 调用的最佳方式》,感兴趣的朋友请继续看下去吧!以下内容将会涉及到等等知识点,如果你是正在学习Golang或者已经是大佬级别了,都非常欢迎也希望大家都能给我建议评论哈~希望能帮助到大家!

问题内容

如何以线程安全的方式进行延迟的、可重新启动的函数调用?这是一个非常常见的用例,例如,如果您想对某些更改做出反应,但频率不超过 x 毫秒一次。

我能想到的代码是:

var t *time.Timer
func restartableDelayed()  {
    if t != nil {
        t.Stop()
    }
    t = time.AfterFunc(time.Second, func() {
        t = nil
        // ...
        // Do the stuff here
        // ...
    })
}

这里明显的问题是 t = nil 分配是从另一个 goroutine 调用的,而不是初始分配,这会受到竞争的影响。

如何以适当的并发安全方式完成此操作?这里我唯一能想到的就是涉及一个互斥体来同步对t的访问,但这感觉有点麻烦。还有更简洁的选择吗?


解决方案


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

您只需添加几行即可开始使用:

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
    })
}

本篇关于《执行可重启和线程安全的 AfterFunc() 调用的最佳方式》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>