Are some prints asynchroneous?

blov · · 434 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I was playing on <a href="https://tour.golang.org/flowcontrol/8">the Golang website</a> when this code:</p> <pre><code>package main import ( &#34;fmt&#34; &#34;math&#34; ) func Sqrt(x float64) float64 { z := x for i := 0; i &lt; 10; i++ { z = z - (z*z-x)/(2*z) fmt.Println(z) } return z } func main() { n := -0.5 r1 := Sqrt(n) r2 := math.Sqrt(n) println(&#34;result&#34;) fmt.Println(r1) fmt.Println(r2) } </code></pre> <p>gave me this result:</p> <pre><code>0.25 -0.875 -0.1517857142857143 1.5711659663865545 0.6264654836111277 -0.08583154272441196 2.869766350671885 1.347768069278103 0.4883921791049566 -0.26768761926971896 -0.26768761926971896 NaN result </code></pre> <p>&#34;result&#34; got printed after r1 and r2. How is that possible?</p> <hr/>**评论:**<br/><br/>VerilyAMonkey: <pre><p>fmt.Println goes to stdout, while println goes to stderr.</p> <p>So, stdout is buffered, and stderr is not. That means when you print to stdout, it doesn&#39;t actually appear until the buffer gets flushed. It&#39;s more efficient that way. Whereas writing to stderr appears immediately.</p> <p>If you write to both, that means stderr stuff can randomly appear in the middle of stdout stuff, at a spot between buffer flushes. </p></pre>au_travail: <pre><p>Well, here two prints to stdout appear before a print to stderr, when code order would suggest otherwise.</p></pre>VerilyAMonkey: <pre><p>Haha, that&#39;s true now that you mention it. So in truth, stdout and stderr are first and foremost different and therefore unsynchronized, so I guess that kind of thing can happen too. On most computers I&#39;ve used it doesn&#39;t, that I&#39;ve seen, and it doesn&#39;t if I run it locally, but that depends on the state of the Go Playground and also a lot of other factors outside of simply the code you&#39;re running. The Go Playground is frequently a little bit different from a normal computer when it comes to concurrency so I&#39;m not too surprised. </p></pre>abhayakara: <pre><p>Ah. Here is your answer: <a href="http://stackoverflow.com/questions/14680255/whats-the-difference-between-fmt-println-and-println-in-go">http://stackoverflow.com/questions/14680255/whats-the-difference-between-fmt-println-and-println-in-go</a></p> <p>To summarize, println prints to stderr, fmt.println prints to stdout.</p> <p>(I&#39;m a go n00b, so it was interesting for me to find the answer... :)</p></pre>nhooyr: <pre><p>It is documented at <a href="https://golang.org/pkg/builtin/#println" rel="nofollow">https://golang.org/pkg/builtin/#println</a></p></pre>au_travail: <pre><p>Yeah but why would &#34;result&#34; get printed after r1 and r2 in this particular case when I iterate Newton&#39;s method 10 times and not when I iterate it 9 or 11 times?</p></pre>au_travail: <pre><p>By &#34;11 times&#34;, I mean this program:</p> <pre><code>package main import ( &#34;fmt&#34; &#34;math&#34; ) func Sqrt(x float64) float64 { z := x for i := 0; i &lt; 11; i++ { z = z - (z*z-x)/(2*z) fmt.Println(z) } return z } func main() { n := -0.5 r1 := Sqrt(n) r2 := math.Sqrt(n) println(&#34;result&#34;) fmt.Println(r1) fmt.Println(r2) } </code></pre> <p>Only change is &#34;10&#34; changed into &#34;11&#34;.</p> <p>It gives this result:</p> <pre><code>0.25 -0.875 -0.1517857142857143 1.5711659663865545 0.6264654836111277 -0.08583154272441196 2.869766350671885 1.347768069278103 0.4883921791049566 -0.26768761926971896 0.8000805933017697 result 0.8000805933017697 NaN </code></pre> <p>With &#34;result&#34; at the right place this time.</p></pre>rsc: <pre><p>This doesn&#39;t happen normally. It&#39;s a playground bug. Please file an issue. Thanks. </p></pre>au_travail: <pre><p>I would like to but my github account has identifying information while this reddit account doesn&#39;t and is meant to stay that way.</p></pre>tdewolff: <pre><p>So, you want to make an anonymous bug report? Why don&#39;t you make a new GitHub account just for anonymous bug reports? I fail to see why anonymity is important with such a harmless bug report though.</p></pre>au_travail: <pre><p>Anonymity is something I want for this reddit account.</p></pre>abhayakara: <pre><p>If you try to use Newton&#39;s method on a negative number, I don&#39;t think it will converge—the errors will multiply instead of canceling out. That is, z squared - x will be -2x if z is the square root of x, whereas if x were positive, z squared - x would be 0 if z were the square root of x.</p></pre>au_travail: <pre><p>I know that the square roots of a negative number are complex numbers, so I wasn&#39;t expecting a float64 sequence to converge.</p> <p>I was just messing around.</p></pre>abhayakara: <pre><p>Oh, and why did you call println and then fmt.println? Are they printing into the same i/o buffer?</p></pre>au_travail: <pre><p>fmt.println was there already and then I decided to try stuff I read here: <a href="https://www.reddit.com/r/golang/comments/16t661/go_a_nice_language_with_an_annoying_personality/" rel="nofollow">https://www.reddit.com/r/golang/comments/16t661/go_a_nice_language_with_an_annoying_personality/</a></p> <blockquote> <p>You can use print and println instead of fmt.Print. It is actually better because it is easier to find debug print statements.</p> </blockquote> <p>I was able to see in my tries that println has a different format for floats than fmt.println</p> <p>I see in <a href="https://golang.org/pkg/builtin/#println" rel="nofollow">https://golang.org/pkg/builtin/#println</a> that println is deprecated. How likely is it to be removed? Is fmt.println better and why?</p></pre>abhayakara: <pre><p>Apparently println is for low-level debugging, and is present even when the libraries aren&#39;t. So not really something that we need to use in regular practice.</p></pre>

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

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