V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
PureWhiteWu
V2EX  ›  Go 编程语言

有一段 Go 的代码报了 race,但不知道会有什么潜在问题,各位大佬帮忙指点一下

  •  
  •   PureWhiteWu ·
    PureWhiteWu · 2019-07-05 19:11:58 +08:00 · 3485 次点击
    这是一个创建于 1963 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码如下:

    package main
    
    import (
    	"sync"
    	"sync/atomic"
    )
    
    func main() {
    	var n int32
    	var m sync.RWMutex
    	go func() {
    		for {
    			atomic.LoadInt32(&n)
    		}
    	}()
    	go func() {
    		for {
    			m.RLock()
    			atomic.AddInt32(&n, 1)
    			m.RUnlock()
    		}
    	}()
    	go func() {
    		for {
    			m.Lock()
    			n = 0
    			m.Unlock()
    		}
    	}()
    	go func() {
    		for {
    			m.Lock()
    			n -= 1
    			m.Unlock()
    		}
    	}()
        // do something to keep goroutines running here
    	......
    }
    
    

    playground link: https://play.golang.org/p/Mrdetw46mXR

    race 内容:

    $ go run -race main.go
    ==================
    WARNING: DATA RACE
    Write at 0x00c000096000 by goroutine 7:
      main.main.func3()
          /Users/purewhite/go/src/xxx/main.go:26 +0x46
    
    Previous read at 0x00c000096000 by goroutine 5:
      sync/atomic.LoadInt32()
          /usr/local/Cellar/go/1.12.6/libexec/src/runtime/race_amd64.s:206 +0xb
      main.main.func1()
          /Users/purewhite/go/src/xxx/main.go:13 +0x38
    
    Goroutine 7 (running) created at:
      main.main()
          /Users/purewhite/go/src/xxx/main.go:23 +0x115
    
    Goroutine 5 (running) created at:
      main.main()
          /Users/purewhite/go/src/xxx/main.go:11 +0xbd
    ==================
    Found 1 data race(s)
    exit status 66
    
    5 条回复    2019-07-06 00:19:17 +08:00
    fork
        1
    fork  
       2019-07-05 19:41:17 +08:00
    把 mutex 去了,
    用 atomic.StoreInt32(&n, 0) 代替 n = 0
    用 atomic.AddInt32(&n, -1) 代替 n -= 1
    100knights
        2
    100knights  
       2019-07-05 22:02:23 +08:00
    为啥你修改要用读锁?
    liulaomo
        3
    liulaomo  
       2019-07-05 22:33:59 +08:00
    这写法看着真别扭。很明显第一个协程和第三第四个有竞争。
    按照你这种写法,你可以把第一个和第二个一样加个读锁。
    whoami9894
        4
    whoami9894  
       2019-07-05 23:06:58 +08:00 via Android
    为什么原子操作还加锁
    reus
        5
    reus  
       2019-07-06 00:19:17 +08:00
    要么全部用锁,要么全部用原子操作,混用就是 race 啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3032 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:32 · PVG 22:32 · LAX 06:32 · JFK 09:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.