goroutines channels problem with unbounded data

xuanbao · · 500 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi,</p> <p>how can i use goroutines to send random data into a channel and wait until all goroutines are finished?</p> <p>I tried with this code but does not work, any suggestion, ideas?</p> <p><a href="https://play.golang.org/p/VPmGM_bhhq" rel="nofollow">https://play.golang.org/p/VPmGM_bhhq</a></p> <hr/>**评论:**<br/><br/>anupcshan: <pre><pre><code>for data := range out { fmt.Printf(&#34;Got data: &#39;%s&#39;\n&#34;, data) } </code></pre> <p>does not terminate till <code>close(out)</code> is called.</p> <p>So, you&#39;ll need another entity waiting for all writer goroutines to complete and close the channel. Something like <a href="https://play.golang.org/p/_ues10N6Bj" rel="nofollow">https://play.golang.org/p/_ues10N6Bj</a></p></pre>Volox: <pre><p>Ok but in this case the program can terminate before the goroutines are completed. Since the <code>wg.Wait()</code> is in a goroutine the code does not wait for a goroutine to complete, so it just exit.</p></pre>Fwippy: <pre><p>No, the main function is waiting for that channel to close before it can exit that for loop. It won&#39;t ever terminate early.</p></pre>Volox: <pre><p>I think not, here is an example code: <a href="https://play.golang.org/p/pYOZvBEZf5" rel="nofollow">https://play.golang.org/p/pYOZvBEZf5</a></p></pre>anupcshan: <pre><p>Output from <a href="https://play.golang.org/p/pYOZvBEZf5:" rel="nofollow">https://play.golang.org/p/pYOZvBEZf5:</a></p> <pre><code>Test coroutine Spawn coroutines CO[0] have 1 elements CO[1] have 2 elements CO[2] have 1 elements CO[3] have 0 elements CO[4] have 0 elements Got data: &#39;CO[1] = 0&#39; Got data: &#39;CO[2] = 0&#39; Got data: &#39;CO[0] = 0&#39; Got data: &#39;CO[1] = 1&#39; </code></pre> <p>This looks accurate. 4 elements were created and added to the channel. All 4 got printed out. What was the expected output?</p></pre>Volox: <pre><p>Sorry, it was my fault, the output is correct. But i cannot run it in my computer.</p> <p>I just copy pasted it and used <code>go run main.go</code> my go version is 1.5.1. Any ideas?</p></pre>Volox: <pre><p>Ok, there were some issues in the code, this works also on my machine: <a href="https://play.golang.org/p/yacwB_DvRM" rel="nofollow">https://play.golang.org/p/yacwB_DvRM</a></p> <p>Thanks for the support!</p></pre>hayzeus: <pre><p>anupcshan is correct. The for... range statement, and thus main(), will not terminate until channel out is closed. out is not closed until wg.Wait() completes in the go routine. So main() can never terminate early.</p></pre>Volox: <pre><p>Sorry, it was my fault, the output is correct. See my response to <a href="/u/anupcshan" rel="nofollow">/u/anupcshan</a>.</p></pre>hayzeus: <pre><p>No worries. I had to look twice myself</p></pre>klauspost: <pre><p>Your for-loop will never exit, since the channel is never closed. </p> <p>See <a href="https://gobyexample.com/range-over-channels" rel="nofollow">Range over Channels</a>.</p></pre>Volox: <pre><p>I&#39;ve seen it the problem is that i do not know when to close the out channel. In theory i need to close it after all the goroutines are completed; but if i do so i have the same problem. See <a href="https://play.golang.org/p/NOGYfVrdU6" rel="nofollow">https://play.golang.org/p/NOGYfVrdU6</a></p></pre>Fwippy: <pre><p>This one deadlocks because the (unbuffered) channel is full after one worker writes to it.</p> <p>The other three workers are waiting to have room to deposit their message, and main is waiting for all messages to be deposited before reading them out.</p> <p>You could solve this with a buffered channel greater than the length of your data, but a better solution is to read the data out as it comes in (as the other solution by anupcshan does)</p></pre>Volox: <pre><p>The solution by <a href="/u/anupcshan" rel="nofollow">/u/anupcshan</a> does not work. See here <a href="https://play.golang.org/p/pYOZvBEZf5" rel="nofollow">https://play.golang.org/p/pYOZvBEZf5</a></p> <p>Besides, I do not know how much data is generated by the gorotines.</p></pre>cmikk: <pre><p>The above appears to be working, as far as I can tell. You&#39;re not hearing from all goroutines because some of them send zero strings before exiting.</p></pre>hayzeus: <pre><p>Exactly -- sometimes the random number is 0</p></pre>Volox: <pre><p>Sorry, it was my fault, the output is correct. See my response to <a href="/u/anupcshan" rel="nofollow">/u/anupcshan</a>.</p></pre>hayzeus: <pre><p>How does this not work? The data seems exactly correct, even with larger values for rand.Intn</p></pre>Volox: <pre><p>Sorry, it was my fault, the output is correct. See my response to <a href="/u/anupcshan" rel="nofollow">/u/anupcshan</a>.</p></pre>apoydence: <pre><p>You&#39;ve fallen for the trap of multiple go routines writing to the same channel.</p> <p>You need some form of a semaphore to determine when to close it. At least that is an option.</p></pre>

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

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