猿问

更改地图链接是否并发安全?

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


一个例子是在一个 goroutine 中将 mapdata替换为新的 map,并在另一个 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

}


三国纷争
浏览 117回答 2
2回答

侃侃尔雅

当然,这并不安全。没有任何变量(包括映射)对于并发读写是安全的。您的一个 goroutine 写入data,另一个读取它。运行测试go test -race还会报告数据竞争:testing.go:954:&nbsp;race&nbsp;detected&nbsp;during&nbsp;execution&nbsp;of&nbsp;test您必须从多个 goroutine 同步读取和写入data变量。

萧十郎

不是的,更新数据时使用sync.Mutex 锁定并解锁。
随时随地看视频慕课网APP

相关分类

Go
我要回答