Go 1.6: fatal error: concurrent map read and map write

xuanbao · · 3197 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi all,</p> <p>I have a wrapper struct around map to provide thread safety. See:</p> <pre><code>import &#34;sync&#34; type struct MyMap { Data map[string]string sync.RWMutex } func (s *MyMap) Set(key string, value string) { s.Lock() s.Data[key] = value s.Unlock() } func (s *MyMap) Get(key string) string { s.RLock() defer s.RUnlock() return s.Data[key] } </code></pre> <p>Nothing special, I bet most of you have this kind of data structure in your codebase.</p> <p>In Go 1.6, <code>s.RLock(); defer s.RUnlock()</code> no longer protect me from race condition. What am I missing?</p> <p><strong>UPDATE:</strong> The answer is that I was sharing the map in <code>All()</code> method instead of copying.</p> <hr/>**评论:**<br/><br/>allhatenocattle: <pre><p>For this type of struct, why is the Data field being exported? It seems like you might be accidentally accessing Data directly somewhere without using Set/Get. I am also curious to see the actual error and source code that demonstrates the problem. </p></pre>pinpinbo: <pre><p>Sorry for the delayed response.</p> <p>Great point, I&#39;ll change it to private and run <code>-race</code> again, see what I stumble next.</p></pre>dgryski: <pre><p>I agree that looks like it should work. Can you produce an entire program that demonstrates the issue? Is there a race somewhere else? What does the race detector say?</p></pre>dgryski: <pre><p>Also, please run go vet and make sure you&#39;re never passing a MyMap by value. </p></pre>pinpinbo: <pre><p>Sorry for the delayed response:</p> <p>You can see the full library here: <a href="https://github.com/resourced/resourced/blob/master/libmap/libmap.go" rel="nofollow">https://github.com/resourced/resourced/blob/master/libmap/libmap.go</a></p> <p>I captured the <code>-race</code> stack trace here: <a href="https://gist.github.com/didip/bd8b49f6b18fa6ee4190" rel="nofollow">https://gist.github.com/didip/bd8b49f6b18fa6ee4190</a></p> <p>Nothing surprising, typical race problem: 1 thread tries to set() and the other one tries to get()</p> <p><code>go vet</code> does not return anything.</p></pre>earthboundkid: <pre><p><code>All</code> returns the original map, not a copy, thereby bypassing all locks. You need to grab the lock and do a full copy instead. </p></pre>pinpinbo: <pre><p>Yup, this is the answer. I was sharing map instead of copying. Thanks!</p></pre>danielt0shea: <pre><p>Is it possible that you call NewTSafeMapCounter with an existing map parameter and the map is used by two go-routines?</p></pre>pinpinbo: <pre><p>Yup, this is the answer. I was sharing map instead of copying. Thanks!</p></pre>danielt0shea: <pre><p>If you run the race detector what does it say?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3197 次点击  
加入收藏 微博
0 回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传