dousi9215 2018-07-28 10:41
浏览 35
已采纳

为什么goroutine无法读取全局var ops值?

package main

import "fmt"
import "time"
import (
    "runtime"
    "sync/atomic"
)

func init() {
    runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
    var t1 = time.Now()
    var ops uint64 = 0
    go func() {
        for {
            time.Sleep(time.Second)
            opsFinal := atomic.LoadUint64(&ops)
            fmt.Println("ops:", opsFinal, "qps:", opsFinal/uint64(time.Since(t1).Seconds()))
        }
    }()

    for {
        atomic.AddUint64(&ops, 1)
        //runtime.Gosched()
    }
}

In this case out put "ops: 0 qps: 0" every second, why canot read ops in goroutine ?

but when add runtime.Gosched(), everything is ok!

Can every body help me?

  • 写回答

2条回答 默认 最新

  • dsuw85815 2018-07-28 15:39
    关注

    My read of The Go Memory Model is that this is a correct execution of the program you've written: nothing guarantees that the AddUint64() calls in the main program happen before the LoadUint64() calls in the goroutine, so it's legitimate for every read of the variable to happen before any write occurs. I wouldn't be totally shocked if the compiler knew about "sync/atomic" as special and concluded that the result of the increment was unobservable, so just deleted the final loop.

    Both The Go Memory Model and the sync/atomic documentation recommend against the approach you're using. "sync/atomic" admonishes:

    Share memory by communicating; don't communicate by sharing memory.

    A better program might look like this:

    package main
    
    import "fmt"
    import "time"
    
    func count(op <-chan struct{}) {
        t1 := time.Now()
        ops := 0
        tick := time.Tick(time.Second)
        for {
            select {
            case <-op:
                ops++
            case <-tick:
                dt := time.Since(t1).Seconds()
                fmt.Printf("ops: %d qps: %f
    ", ops, float64(ops)/dt)
            }
        }
    }
    
    func main() {
        op := make(chan struct{})
        go count(op)
        for {
            op <- struct{}{}
        }
    }
    

    Note that no state is shared between the main program and the goroutine, except the data that is sent across the channel.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog