Golang channel is really FIFO?

xuanbao · · 520 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi,</p> <p>I heard that channel is FIFO (like queue system), but when I run this code, I feel it is LIFO. </p> <p><a href="https://play.golang.org/p/pbnPMOqr22" rel="nofollow">code!</a></p> <p>Please help.</p> <hr/>**评论:**<br/><br/>kostix: <pre><p>The two goroutines you have create run concurrently and hence the order they push to the channel is unpredictable.</p> <p>So, the Go channels are FIFO, you just have an unpredictable order of who goes first and who goes last <em>into</em> your channel.</p></pre>md2perpe: <pre><p>You can&#39;t know in which order the two go-routines are run.</p></pre>9nut: <pre><p>Both goroutines block until the receive can succeed. The first receive allows a send in one of the blocked routines to succeed (undetermined order). There is no guaranteed order in goroutine scheduling.u</p></pre>SourLemon15: <pre><p>Please keep in mind that the Go Playground is deterministic, meaning you should get the same result each time you run a program on the <a href="https://play.golang.org" rel="nofollow">https://play.golang.org</a> website.</p> <p>If you run it several times on your local machine with the <code>go run</code> command you should see that sometimes <code>x</code> is <code>-5</code> and sometimes it&#39;s <code>17</code> because you can&#39;t predict which order the goroutines will be executed in, or if they are executing in parallel, which one will finish first.</p> <p>So basically, channels are FIFO, but the Go Playground is always showing you <code>x</code> as being <code>-5</code> because that&#39;s just the way the Go Playground is running your program every single time.</p> <p>In addition to the deliberate determinism in the Go Playground, I believe they also cache the results of programs as well.</p></pre>Veonik: <pre><p>I didn&#39;t know this! I was dubious so I had to try it out myself: <a href="https://play.golang.org/p/dhMO7xLZwn" rel="nofollow">https://play.golang.org/p/dhMO7xLZwn</a></p> <p>Super weird. I wonder if it&#39;s a function of caching the output that causes this, and not the playground&#39;s Go runtime being different. I feel like the latter would cause issues since code running on the playground would not behave the same as code running locally.</p></pre>SourLemon15: <pre><p>I know that the go playground is frozen in time, that is, you will always get the same time from a call to <code>time.Now</code> for example, so it’s deterministic in that way. They also use some other tricks to fake things like <code>time.Sleep</code>, the file system and the network, which you can read about here: <a href="https://blog.golang.org/playground" rel="nofollow">https://blog.golang.org/playground</a></p> <p>I don’t know how their modifications for the go playground affect things like goroutines or map key order though, so I would assume that those are to do with the caching, which is why I mentioned it. I don’t know how long the cache lasts, but it could be that if you happen to run the program again after the cache is invalidated that you might get a different result which would then be cached again.</p></pre>nemith: <pre><p>Most random seeds are based on the timestamp. If time is frozen then so are randomized seeds which could be used to determine which goroutine to run next if both are available.</p></pre>SourLemon15: <pre><p>That’s what I was thinking too, but I couldn’t find anything written by the Go team about it so the caching seemed worthwhile to mention as well. </p></pre>iris-go: <pre><p>You can find the source code of both Go Playground and Go Tour at: <a href="https://github.com/golang/playground" rel="nofollow">https://github.com/golang/playground</a> and <a href="https://github.com/golang/tour" rel="nofollow">https://github.com/golang/tour</a> respectfully.</p></pre>0xjnml: <pre><p>A channel with buffer of zero items cannot have LIFO nor FIFO nor any other ordering semantics and the observed ordering of the values is decided only by the scheduler algorithm which is nowhere guaranteed to be deterministic. Actually, the more it&#39;s fair randomness, the better.</p></pre>jabbrwcky: <pre><p>If you switch the order of the go-routines the order also changes. I suspect (without digging into it) that it is related to the internal workings of go-routines - the compiler likely reorders code execution.</p> <p>If you change the channel to a buffered channel and omit the go-routines it actuall behaves like you&#39;d expect: <a href="https://play.golang.org/p/NPb7khoh-F" rel="nofollow">https://play.golang.org/p/NPb7khoh-F</a></p></pre>

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

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