go中的fatal error:concurrent map read and map write

在Go中,如果不对map做同步控制,高并发读写时,会出现fatal级别的错误。复现例子:

错误示例


package rabbit

import (
    "fmt"
    "testing"
    "time"
)

var count = 100000

func Test_NonConcurrentMap(t *testing.T) {
    nonCMap := make(map[int]struct{})
    go WriteNonCMap(nonCMap)
    go ReadNonCMap(nonCMap)

    // To see the fatal
    time.Sleep(10 * time.Second)
}

func WriteNonCMap(nonCMap map[int]struct{}) {
    for index := 0; index < count; index++ {
        nonCMap[index] = struct{}{}
    }
}

func ReadNonCMap(nonCMap map[int]struct{}) {
    for index := 0; index < count; index++ {
        fmt.Print(nonCMap[index])

    }
}

错误结果


测试Test_NonConcurrentMap 函数会报错:fatal error: concurrent map read and map write

image.png

如果恰好没有报错,则可以提升主进程的sleep时间,增大碰撞区间,或增加count的数量,延长碰撞时间。

错误原因

因为这两个程序都是对一个map去访问,当两个协程同时的去访问这个map时,就会发生资源竞争,进而报错。

解决方法

  1. sync.map
package rabbit

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

var count = 100000

func Test_ConcurrentMap(t *testing.T) {
    cMap := &sync.Map{}
    go WriteCMap(cMap)
    go ReadCMap(cMap)

    // Never fatal
    time.Sleep(10 * time.Second)
}

func WriteCMap(cMap *sync.Map) {
    for index := 0; index < count; index++ {
        cMap.Store(index, struct{}{})
    }
}

func ReadCMap(cMap *sync.Map) {
    for index := 0; index < count; index++ {
        fmt.Print(cMap.Load(index))
    }
}
  1. channel
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容