2010-07-19 148 views
4

我嘗試寫一些小超時代碼:爲什麼此代碼打印兩次相同的東西?

t = Thread.new { sleep 3 } # <- The thread that will do stuff. 
Thread.new { sleep 2; t.kill; p 'hi!' } # <- The thread that will kill it after two seconds. 
t.join 

如果第一個線程完成它的兩秒鐘之內的工作,它就會停止,而主線程將無事可做。這會導致程序在第二個線程到達t.kill部分之前退出。但是,當我運行這個代碼時,"hi!"被打印出兩次。用puts替換p可以修復它。爲什麼會發生?

+0

無法重現。 – 2010-07-19 02:53:51

+0

@Marc:我發現如果你在終端輸入'ruby'(不帶參數),只需粘貼代碼並按下Control-D,'「嗨」'只會打印一次。但是,如果你真的把代碼放到一個文件中並執行'ruby test.rb'這樣的事情,它就會發生。我認爲這可能與ruby可以讀取文件的速度和ruby可以讀取stdin的速度有關。 – Adrian 2010-07-19 03:02:41

+1

絕對是一個錯誤。 'ruby somefile.rb'會在大部分時間打印兩次,這是間歇性的。可以在redmine.ruby-lang.org上存檔嗎?你可以爲'ruby -v'指定「ruby 1.9.3dev(2010-07-19 trunk 28679)[x86_64-darwin10.4.0]」,正如我用trunk重現的一樣。或者讓我知道,我會創建這個問題。 – 2010-07-19 03:25:26

回答

1

Ruby有一個IO緩衝和線程的錯誤,看起來就像這樣。它最近已經修復,所以升級。

0

這聽起來像我喜歡「嗨!」被緩衝起來並刷新兩次,一次是通過執行p操作的匿名線程,一次通過主線程。如果這是一個C程序,修復它的方法是禁用stdout上的緩衝,否則使用write跳過fd 1,繞過stdio。據推測,Ruby至少有這些選項中的第一個相當於?