dpchen2004
2019-05-23 11:19 阅读 74
已采纳

Golang并发写入变量-为什么此代码有效?

I'm learning concurrency-related issues in Golang. I wrote some code:

package main

import (
    "fmt"
    "time"
)

func incr(num *int) {
    *num = *num + 1

}

func main() {
    var a = 0

    for i := 0; i < 50; i++ {
        go incr(&a)
    }

    incr(&a)

    time.Sleep(1 * time.Second)
    fmt.Println(a)
}

The result of this code is: 51

In this code I've declared a variable which I'm increasing in 50 running goroutines. What I've read and unsterstood this code should fail because multiple goroutines are writing to same memory address. In this case I should add sync.Mutex lock in order to fix that.

Code is available in the playground: https://play.golang.org/p/Tba9pfpxaHY

Could You explain what is really happening in this program?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    dongxi1879 dongxi1879 2019-05-23 11:34

    Guess what? I ran your app and I get varying outputs: sometimes 49, sometimes 48, sometimes 50 (and sometimes 51).

    If you run your app with the race detector enabled (go run -race play.go), it tells you have data races:

    ==================
    WARNING: DATA RACE
    Read at 0x00c00009a010 by goroutine 7:
      main.incr()
          /home/icza/gows/src/play/play.go:9 +0x3a
    
    Previous write at 0x00c00009a010 by goroutine 6:
      main.incr()
          /home/icza/gows/src/play/play.go:9 +0x50
    
    Goroutine 7 (running) created at:
      main.main()
          /home/icza/gows/src/play/play.go:17 +0x83
    
    Goroutine 6 (finished) created at:
      main.main()
          /home/icza/gows/src/play/play.go:17 +0x83
    ==================
    

    When you have data races, the behavior of your app is undefined. "Seemingly working sometimes" also fits into the "undefined" behavior, but undefined also means it can do anything else too.

    See related questions:

    Assign a map to another map is safety in golang?

    Is it safe to read a function pointer concurrently without a lock?

    golang struct concurrent read and write without Lock is also running ok?

    点赞 评论 复制链接分享

相关推荐