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

在并发goroutine期间如何锁定/同步Go中对变量的访问?

在并发goroutine期间如何锁定/同步Go中对变量的访问?

Go
撒科打诨 2021-04-30 22:09:21
在他对以下问题的回答中: Golang for Windows行为不稳定? 建议用户@distributed锁定/同步并发goroutine上对共享变量的访问。我怎样才能做到这一点?有关此问题的更多信息:我获得views了同时在多个goroutines上运行的代码(带有闭包的返回函数):func makeHomeHandler() func(c *http.Conn, r *http.Request) {    views := 1    return func(c *http.Conn, r *http.Request) {        fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)        views++    }}看起来IO功能很费时间,结果我得到了这种输出:Counting monkeys, 5 so far.Counting monkeys, 5 so far.Counting monkeys, 5 so far.Counting monkeys, 8 so far.Counting monkeys, 8 so far.Counting monkeys, 8 so far.Counting monkeys, 11 so far.它可以很好地递增,但是当它被打印时,我可以看到print + incrementing操作不是原子的。如果我将其更改为:func makeHomeHandler() func(c *http.Conn, r *http.Request) {    views := 0    return func(c *http.Conn, r *http.Request) {        views++        // I can only hope that other goroutine does not increment the counter         // at this point, i.e., right after the previous line and before the         // next one are executed!        views_now := views        fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views_now)    }}似乎工作正常,但我不确定是否最终不会失败...
查看完整描述

2 回答

?
哔哔one

TA贡献1854条经验 获得超8个赞

的同步包有一些同步原语。根据问题,您可以使用RWMutex或普通的Mutex。


如果您想要更具体的答案,请提供更多信息。


编辑:阅读链接的问题后,您可能正在寻找sync / atomic,尽管Mutex也很好。


Edit2:我看到您用示例更新了您的帖子。这是使用同步/原子的代码。


func makeHomeHandler() func(w http.ResponseWriter, r *http.Request) {

    var views *uint64 = new(uint64)

    atomic.StoreUint64(views, 0) // I don't think this is strictly necessary

    return func(w http.ResponseWriter, r *http.Request) {

        // Atomically add one to views and get the new value

        // Perhaps you want to subtract one here

        views_now := atomic.AddUint64(views, 1) 

        fmt.Fprintf(w, "Counting %s, %d so far.", r.URL.Path[1:], views_now)

    }

}


查看完整回答
反对 回复 2021-05-10
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

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