go map fatal errorconcurrent map read and map write

本文探讨了Go语言中并发读写map导致的`fatalerror:concurrentmapreadandmapwrite`错误,分析了问题原因并提出了两种解决方法:使用锁(包括普通锁和读写锁)以及通过channel实现串行化处理。通过加锁确保对map的访问互斥,或者借助channel避免并发冲突,可以有效解决Go中map的并发安全问题。

go map fatal error:concurrent map read and map write

golang中map并发读写问题及解决方法

go语言切片slice的线程协程安全问题

一、map并发读写问题

如果map由多协程同时读和写就会出现fatalerror:concurrentmapreadandmapwrite的错误

如下代码很容易就出现map并发读写问题

funcmain(){

c:=make(map[string]int)
Gofunc(){//开一个协程写map
forj:=0;j<1000000;j++{
c[fmt.Sprintf(“%d”,j)]=j
}
}()
gofunc(){//开一个协程读map
forj:=0;j<1000000;j++{
fmt.Println(c[fmt.Sprintf(“%d”,j)])
}
}()

time.Sleep(time.Second*20)

}

多个协程同时写也会出现fatalerror:concurrentmapwrites的错误

如下代码很容易出现map并发写的问题

func main(){

c:=make(map[string]int)

fori:=0;i<100;i++{
gofunc(){  //开100个协程并发写map
forj:=0;j<1000000;j++{
c[fmt.Sprintf(“%d”,j)]=j
}
}()
}
time.Sleep(time.Second*20)//让执行main函数的主协成等待20s,不然不会执行上面的并发操作

}

二、出现问题的原因

因为map为引用类型,所以即使函数传值调用,参数副本依然指向映射m,所以多个goroutine并发写同一个映射m,写过多线程程序的同学都知道,对于共享变量,资源,并发读写会产生竞争的,故共享资源遭到破坏

三、解决方法

1、加锁

(1)通用锁

typeDemostruct{

Datamap[string]string

Locksync.Mutex

}

func(dDemo)Get(kstring)string{

d.Lock.Lock()

deferd.Lock.UnLock()

returnd.Data[k]

}

func(dDemo)Set(k,vstring){

d.Lock.Lock()

deferd.Lock.UnLock()

d.Data[k]=v

}

(2)读写锁

type MapTplResCode struct {

Data map[ string] int

Lock *sync.RWMutex

}

func (d MapTplResCode) Get(k string) ( int, bool) {

d.Lock. RLock()

defer d.Lock. RUnlock()

if v, ok := d.Data[k]; ok {

return v, true

}

return 0, false

}

func (d MapTplResCode) Set(k string, v int) {

d.Lock. Lock()

defer d.Lock. Unlock()

d.Data[k] = v

}

func (d MapTplResCode) Init() {

d.Lock. Lock()

defer d.Lock. Unlock()

//d.Data = make(map[string]int)

for key, _ := range d.Data {

delete(d.Data, key)

}

}

2、利用channel串行化处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值