golang map 读写锁与深度拷贝的坑

0X01

golang中,map(字典)无法并发读写

简单来说,新建万条线程对同一个map又读又写,会报错。

为此,最好加锁,其实性能影响并不明显。

type taskCache struct{
    sync.RWMutex
    data map[string] interface{}
}

 

 

0X02

golang中,map(字典)为引用拷贝。

a = 字典一

b = a 

实际上是直接将指针传给了b。

 

于是,有一个读取,写的时候直接读map并返回

func GetAllTasks() (result map[string]interface{}, err error) {
    // 获得当前的所有任务
    DEMO.RLock()
    defer DEMO.RUnlock()
    return DEMO.data, err
}

而在线程中

// 接收后直接打印
fmt.Println(store.GetAllTasks())

结果居然报错,map读写冲突。

 

于是,我返回去一遍一遍看代码,觉得自己的读写锁写错了。

调式折腾了半天,最后发现,在接收后不用 fmt.Println 打印就不会报错。

这很不科学,然后在接收打印前后加上读锁,不报错了。

 

0X03

所以golang,加了读写锁的时候,要返回全部值,还不能直接返回这个字典,因为直接返回这个字典,返回了指针,操作的时候要不还要加读写锁,要不就报错。

还没有直接的取地址的值重新给另一个变量的东西,自己写个遍历,一个一个赋值吧,蛋疼,坑货,坑了一晚上

var cache = make(map[string]interface{})
for k,v := range Demo.data{
    cache[k] = v
}

 

转载于:https://www.cnblogs.com/huim/p/10073837.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值