美文网首页工作生活
go中的fatal error:concurrent map r

go中的fatal error:concurrent map r

作者: 天地一小儒 | 来源:发表于2019-07-01 18:17 被阅读0次

    在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

    相关文章

      网友评论

        本文标题:go中的fatal error:concurrent map r

        本文链接:https://www.haomeiwen.com/subject/mibgcctx.html