Musing on shared variables, channels, and closures.

xuanbao · · 646 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Nothing too exciting here. Just a novice playing around.</p> <p>So I was thinking about using mutex vs. using channels. I came up with this as an alternative to using mutex locks. <a href="http://play.golang.org/p/e0RuSXqnYB">http://play.golang.org/p/e0RuSXqnYB</a></p> <p>I imagine this isn&#39;t the first time someone has thought of sharing a variable through a goroutine.</p> <p>Any thoughts in general on the pattern? Performance, readability, reliability? Any reading material you&#39;d like to send my way on the topic?</p> <p>Thanks.</p> <hr/>**评论:**<br/><br/>TheMerovius: <pre><p>Don&#39;t simulate a sync.Mutex, just use a sync.Mutex. I think it takes hits on all fronts (except reliability). Compare with <a href="http://play.golang.org/p/31McBb67Ko">this</a>. This is also better because you can make it a RWMutex, to reduce lock-contention when you write it seldom and read it often.</p> <p>You also don&#39;t include any code to stop the started goroutine which might lead to resource leaks.</p> <p><a href="http://play.golang.org/p/KIjrnZENH0">This pattern</a> is a <em>bit</em> more appealing to me than locking, if you want to enable the same usecases.</p> <p>Overall, I think it depends much on the usecases you have. I wouldn&#39;t try to simulate usages of sync Primitives, but instead focus on the pattern of giving a goroutine exclusive use over a resource and offer an API to it via channels.</p> <p>[edit] Forgot that I wanted to also demostrate how to <a href="http://play.golang.org/p/cyUHWi6Ub-">abort the goroutine</a></p></pre>IntellectualReserve: <pre><p>Thanks for your reply! </p> <p>In your second example, channel i accepts both reads and writes. Wouldn&#39;t that be unreliable?</p> <p>For example, suppose several goroutines are trying to read the channel and a couple are trying to write, isn&#39;t it possible that the write message might end up being received by a goroutine other than the goroutine managing the value?</p></pre>TheMerovius: <pre><blockquote> <p>For example, suppose several goroutines are trying to read the channel and a couple are trying to write, isn&#39;t it possible that the write message might end up being received by a goroutine other than the goroutine managing the value?</p> </blockquote> <p>I think you are right. I haven&#39;t thought about that. You can adapt that part, but I was mainly refering to the function part. Indeed, you don&#39;t even <em>need</em> the second channel, because the closure approach is <a href="http://play.golang.org/p/5QICcnahp8" rel="nofollow">pretty damn flexible</a>, though admittedly, it&#39;s a tad complicated to get the value. [edit] a <a href="http://play.golang.org/p/FfPLV4lSlb" rel="nofollow">hybrid approach</a> might solve both problems [/edit]</p> <p>But my main point was: Don&#39;t emulate a lock. Just use the lock that&#39;s already there. It&#39;s clearer, faster and probably about as reliable. :)</p></pre>borring: <pre><blockquote> <p>You also don&#39;t include any code to stop the started goroutine which might lead to resource leaks.</p> </blockquote> <p>Is this bad practice even if the goroutine is supposed to run for the whole duration of the program? Don&#39;t the goroutines end when main returns anyway?</p></pre>TheMerovius: <pre><p>Well, if you <em>know</em> that it doesn&#39;t, it won&#39;t really matter (unless it holds on to resources like files). But for your code to be flexible enough, you should definitiely <em>try</em> to include it.</p></pre>IntellectualReserve: <pre><p>So, I decided to do some performance testing. Using channels instead of mutex locks took about 10 times as long. I&#39;ll post the code in an hour. </p></pre>augorak: <pre><p>You aren&#39;t using channels <em>instead</em> of mutexes. Channels are implemented <em>with</em> mutexes. Channels are a thread-safe abstraction around communicating.</p></pre>TheMerovius: <pre><p>That&#39;s a bit like saying &#34;you don&#39;t use fmt.Println <em>instead</em> of using os.Stdout.Write, fmt.Println is implemented with os.Stdout.Write.&#34;. True, but the original statement is still perfectly fine :)</p></pre>augorak: <pre><p>Yeah I may have phrased it badly but I guess my point was that channels still carry the cost of locking.</p></pre>IntellectualReserve: <pre><p>Ahhh, that makes sense. Thanks! </p></pre>

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

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