Is this code leaking?

xuanbao · · 710 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<pre><code>package main import ( &#34;fmt&#34; &#34;time&#34; ) type result func(int) var res []result func main() { ch := make(chan int) result1 := func(q int) { time.Sleep(10000 * time.Millisecond) ch &lt;- q } result2 := func(q int) { time.Sleep(500 * time.Millisecond) ch &lt;- q } result3 := func(q int) { time.Sleep(1000 * time.Millisecond) ch &lt;- q } res = []result{result1, result2, result3} for i := range res { go res[i](i + 1) } fmt.Printf(&#34;Result Position : %d &#34;, &lt;-ch) } //Outputs Result Position : 2 </code></pre> <p>What happens to the long processing goroutines?</p> <p>Thanks</p> <hr/>**评论:**<br/><br/>Fwippy: <pre><p>Normally, goroutines are not garbage collected or cleaned up until they exit - it doesn&#39;t look and see &#34;Hey, these two goroutines aren&#39;t ever going to do any useful work.&#34;</p> <p>However, a go program exits when its <code>main()</code> function exits, without waiting for any other goroutines to complete. Any remaining goroutines just simply stop abruptly, without calling any <code>defer</code>red functions.</p> <p>Edit: Play link, for formatting: <a href="https://play.golang.org/p/p7Hikt72VE">https://play.golang.org/p/p7Hikt72VE</a></p></pre>srikanthegdee: <pre><p>So you are saying that I dont have to worry about those loose goroutines hanging around? Because I am only waiting for one goroutine and discarding the rest, you think <strong>runtime</strong> takes care of that? Thanks</p></pre>barsonme: <pre><blockquote> <p>So you are saying that I dont have to worry about those loose goroutines hanging around?</p> </blockquote> <p>During the course of your program, yes. As Fwippy said, they&#39;re not garbage collected until they exit, so they could last the lifetime of the program.</p> <p>That said, once <code>main</code> exits Go&#39;s runtime cleans everything up, <em>everything</em> exits, and the memory is given back to the OS.</p></pre>srikanthegdee: <pre><blockquote> <p>they could last the lifetime of the program</p> </blockquote> <p>Thanks for clearing it up. </p></pre>mc_hammerd: <pre><p>are the funcs called in go routines gc collected after those funcs finished?</p></pre>earthboundkid: <pre><p>Yes. You may be interested in <a href="http://blog.carlsensei.com/post/72359081647" rel="nofollow">my blog post about how to use quit channels</a>.</p></pre>bbrazil: <pre><p>The first and third goroutine will hang waiting for the channel to be consumed, as the channel doesn&#39;t have a buffer.</p></pre>srikanthegdee: <pre><p>Thanks, may be I will add capacity 1 to that <strong>chan</strong>. But what happens to other goroutines? Does GC take care of it?</p></pre>funny_falcon: <pre><p>no, it doesn&#39;t. And if your program is long living, then it will be an issue.</p></pre>srikanthegdee: <pre><p>Thanks and yes, the lifetime of those goroutines will be that of the program itself. I wish there was either a GC or auto runtime monitoring for goroutines!!</p></pre>joushou: <pre><p>That sounds like it would be a way too magic feature...! Rather, to make things easy to predict and nice to work with, goroutines do exactly what you tell them to. Try to imagine how hairy debugging would get if goroutines suddenly disappeared when you didn&#39;t expect them to! The Go runtime does provide <em>some</em> monitoring, in the sense that it will error out if you accidentally block all your goroutines in a giant deadlock.</p> <p>Terminating main() doesn&#39;t actually have much to do with the runtime. The operating system considers your application done when main/_main terminates, and anything left behind will be cleaned up by the kernel. The Go runtime could, and might clean things up here, but the default behaviour of any application terminating main is to be killed by a kernel that has seen too much and has nothing to lose...</p></pre>chipaca: <pre><p>Maybe you want to look at <a href="http://blog.labix.org/2011/10/09/death-of-goroutines-under-control" rel="nofollow">tomb</a>?</p></pre>jerf: <pre><p>Consider using a <a href="http://golang.org/pkg/sync/#WaitGroup" rel="nofollow">sync.WaitGroup</a> for this.</p> <p>In general, Go and every other runtime I know will exit when a distinguished thread (or local equivalent, like a goroutine) exits, because as the complexity of the program grows, probability approaches 1 that some thread will fail to exit at the correct time, resulting in the entire program essentially hanging at shut down. Heck, even when things like Windows work like that but allow threads to tell the OS &#34;No, wait, don&#39;t shut me down yet&#34; you get programs hanging, just off that small number of threads that explicitly claims that feature.</p> <p>And for the question of whether it is hung, it is in the general case an instance of the halting problem. In some specific cases the GC/runtime could figure it out (you have a receive-only channel ref, no sendable channel refs exist any longer) but implementing such things is, in a weird way, sort of a bad idea... optimizations like that which only trigger <em>sometimes</em> are sort of worse than ones that never trigger; you depend on them until suddenly, one day, in your huge network program they stop firing, and the first notification you get about that is the 3am pager alert that your site is down. Given Go&#39;s core target audience, that&#39;s not a made-up story... that&#39;s life!</p></pre>

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

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