猿问

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

在他对以下问题的回答中: 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)

    }

}

似乎工作正常,但我不确定是否最终不会失败...


撒科打诨
浏览 174回答 2
2回答

哔哔one

的同步包有一些同步原语。根据问题,您可以使用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)    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答