登录
首页 >  Golang >  Go问答

更改地图链接并发安全吗?

来源:stackoverflow

时间:2024-04-19 17:54:34 439浏览 收藏

大家好,我们又见面了啊~本文《更改地图链接并发安全吗?》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

您知道吗,在并发环境中将映射变量链接更改为另一个链接是否安全?

一个示例是,在一个 goroutine 中将映射 data 替换为新映射,并在另一个 goroutine 中读取其中的元素:

import (
    "fmt"
    "math/rand"
    "strconv"
    "testing"
    "time"
)

func TestMap(t *testing.T) {
    s1 := rand.NewSource(time.Now().UnixNano())
    r1 := rand.New(s1)
    data := fill(r1.Intn(100))

    timer := time.NewTimer(10 * time.Second)

    go func() {
        s1 := rand.NewSource(time.Now().UnixNano())
        r1 := rand.New(s1)

        for {
            select {
            case <-timer.C:
                return
            default:

            }
            p := r1.Intn(100)
            v := fill(p)
            data = v
            fmt.Println("_p=" + strconv.Itoa(p))
        }
    }()

    for range []int{1, 2, 3, 4, 5, 6, 7, 8} {
        go func() {
            s1 := rand.NewSource(time.Now().UnixNano())
            r1 := rand.New(s1)
            for {

                select {
                case <-timer.C:
                    return
                default:

                }

                n := r1.Intn(100)
                s := strconv.Itoa(n)
                fmt.Println(data[s])
            }
        }()
    }

    <-timer.C
}

func fill(postfix int) map[string][]string {
    m := make(map[string][]string)
    for i := 0; i < 100; i++ {
        s := strconv.Itoa(i)
        m[s] = []string{s + "_" + strconv.Itoa(postfix)}
    }
    return m
}

解决方案


当然不安全。没有变量(包括映射)对于并发读写是安全的。

你的一个 goroutine 写入 data,另一个 goroutine 读取它。使用 go test -race 运行测试还会报告数据争用:

testing.go:954: race detected during execution of test

多个goroutine中必须同步读写data变量。

事实并非如此,使用sync.mutex来锁定它,并在更新数据时解锁它。

终于介绍完啦!小伙伴们,这篇关于《更改地图链接并发安全吗?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

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