<span style="font-size:18px;">0X01</span>
golang中,map(字典)无法并发读写
简单来说,新建万条线程对同一个map又读又写,会报错。
为此,最好加锁,其实性能影响并不明显。
<pre><span style="color:#000000;">type taskCache struct{
sync.RWMutex
data map[string] interface{}
}</span></pre>
<span style="font-size:18px;">0X02</span>
golang中,map(字典)为引用拷贝。
a = 字典一
b = a
实际上是直接将指针传给了b。
于是,有一个读取,写的时候直接读map并返回
<pre><span style="color:#000000;">func GetAllTasks() (result map[string]interface{}, err error) {
</span>//<span style="color:#000000;"> 获得当前的所有任务
DEMO.RLock()
defer DEMO.RUnlock()
</span><span style="color:#0000ff;">return</span><span style="color:#000000;"> DEMO.data, err
}</span></pre>
而在线程中
<pre>// 接收后直接打印
fmt.Println(store.GetAllTasks())</pre>
结果居然报错,map读写冲突。
于是,我返回去一遍一遍看代码,觉得自己的读写锁写错了。
调式折腾了半天,最后发现,在接收后不用 fmt.Println 打印就不会报错。
这很不科学,然后在接收打印前后加上读锁,不报错了。
<span style="font-size:18px;">0X03</span>
所以golang,加了读写锁的时候,要返回全部值,还不能直接返回这个字典,因为直接返回这个字典,返回了指针,操作的时候要不还要加读写锁,要不就报错。
还没有直接的取地址的值重新给另一个变量的东西,自己写个遍历,一个一个赋值吧,蛋疼,坑货,坑了一晚上
<pre>var cache =<span style="color:#000000;"> make(map[string]interface{})
</span><span style="color:#0000ff;">for</span> k,v :=<span style="color:#000000;"> range Demo.data{
cache[k] </span>=<span style="color:#000000;"> v
}</span></pre>
<blockquote class="layui-elem-quote" style="width: 100%;overflow:hidden">
作者: Js_123456789
链接: http://www.cnblogs.com/huim/p/10073837.html
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
</blockquote>
到此这篇关于“golang map 读写锁与深度拷贝的坑”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!