在群里看到一段代码,是内存模型的问题还是协程调度的问题呢?

下面代码持续输出0,不能理解,感觉调度是ok的,两个goroutine都有机会调用,但是为啥只输出0呢?

package main

import (
    "fmt"
    "sync"
)

func main() {
    var (
        i  int
        wg sync.WaitGroup
    )

    wg.Add(2)

    go func() {
        for {
            i++
        }
    }()

    go func() {
        for {
            fmt.Println(i)
        }
    }()

    wg.Wait()

}
已邀请:

Laily - 高级复制粘贴工程师

赞同来自: Xss Chaofei

主要看下 go 内存模型的代码,https://golang.org/ref/mem 详细分析可以看这里:https://www.notion.so/laily/Go-b7141b8458f04e10927553381adcd3ad

h12 - https://h12.io/about

赞同来自: Xss

这不正是传说中的竞态条件么?(https://en.wikipedia.org/wiki/Race_condition#Data_race)

并发读写的正确姿势:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var (
        i  int
        mu sync.RWMutex
    )

    go func() {
        for {
            mu.Lock()
            i++
            mu.Unlock()
            time.Sleep(10 * time.Millisecond)
        }
    }()

    go func() {
        for {
            mu.RLock()
            value := i
            mu.RUnlock()
            fmt.Println(value)
        }
    }()

    time.Sleep(500 * time.Millisecond)
}

caicai

赞同来自:

因为输出太快了,第二个goroutine还没有收到i的改变。 你可以在循环里加个sleep就可以看到变化了

lesliehuang

赞同来自:

我偷偷来水一下,顺便看看IV能不能插入视频。 下面(可能会)是我这个非常菜的PV随便做的蝴蝶~ 重庆时时彩视频床是我自建的,完善以后应该会对论坛里的小伙伴们开放~

要回复问题请先登录注册