登录
首页 >  Golang >  Go问答

为何Golang协程表现不同?

来源:stackoverflow

时间:2024-02-17 23:03:25 282浏览 收藏

积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《为何Golang协程表现不同?》,就带大家讲解一下知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

type MapInt map[int]int
var cacheMap unsafe.Pointer //Cach,

func Test_Atomic(t *testing.T) {
    //runtime.GOMAXPROCS(1)
    go func() {
        for i := 0; i < 1000; i++ {
            m1 := MapInt{}
            m1[3] = i                                           //write data
            atomic.StorePointer(&cacheMap, unsafe.Pointer(&m1)) //Atomic Opt
        }
    }()
    //read
    for i := 0; i < 1000; i++ {
        go func() {
            m := *(*MapInt)(cacheMap)
            md := m[3]
            t.Log(md)
        }()
    }
    t.Log("end ")
}

我得到了两个结果

  1. 第一个出现错误

=== 运行测试_原子 恐慌:运行时错误:无效的内存地址或零指针取消引用 [信号0xc0000005代码=0x0地址=0x0pc=0xaff344]

  1. 第二个是运行成功

    ... 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 atom_test.go:31:结束 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 原子测试.go:28:999 --- 通过:test_atomic(0.15s) 通过


正确答案


根据并发代码实际执行的(不确定的)顺序,第一次读取可能会在第一次写入之前执行,从而导致 nil 取消引用恐慌。您需要确保在第一次读取执行之前 cacheMap 中有一个可用的值。

理论要掌握,实操不能落!以上关于《为何Golang协程表现不同?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>