發新話題
打印

Ruby多執行緒教學(初學者適用)

Ruby多執行緒教學(初學者適用)

English version is here.


這篇講的很基礎,因為最近需要寫到multi-threading才測試一下他的行為,以下是參考這篇與自己的實驗結果:

Thread的生命週期
開一個新的thread
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  puts "new thread"
}
puts "main thread end"
要注意一件很重要的事情,如果沒有把Thread instance join的話,主Thread結束後就會把它強制切斷了,跑跑看以下的code:
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  sleep 5
  puts "new thread"
}
# sleep 10 # 跑完以後把這行解開再跑看看
puts "main thread end"
把thread t1 join進來
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  sleep 5
  puts "new thread"
}
t1.join #主thread會停在這邊等t1執行完
puts "main thread end"
但是有多個threads要一起執行的話,千萬不要new出來就join
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  sleep 5
  puts "new thread 1"
}
t1.join # 他會直接在這邊卡5秒
t2=Thread.new{
  sleep 5
  puts "new thread 2"
}
#t1.join #放在這邊才會t1, t2同時執行
t2.join
puts "main thread end"
.


處理例外
如果main thread爆例外的話,程式會中斷並印出錯誤訊息。但如果是新開的thread裡面爆例外的話,預設只會終止該thread,並讓其他繼續跑。如果你希望他會把直譯打斷的話,可以設定t1.abort_on_exception。不過如果你有用t1.join或t1.value的話他就還是會打斷的(因為main thread會停在那兩行指令等待,t1.value就是傳回值,是那個thread block中最後一行的傳回值)
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  sleep 5
  puts a #未定義
  puts "new thread"
}
t1.abort_on_exception = true #預設是false,如果把這行註解掉的話你會發現他會跳過puts "new thread"
sleep 10
puts "main thread end"
但是如果一進入new thread第一行就爆錯誤,預設還是只停該thread,此時我們可以這樣用:
複製內容到剪貼板
代碼:
puts "main thread start"
t1=Thread.new{
  Thread.current.abort_on_exception=true # Thread.current得到的就是自己
  puts a #未定義
  puts "new thread"
}
sleep 10
puts "main thread end"
.


變數scope
新的thread可以讀到更外層的變數,並跟其他同層的new threads共享。但是在Thread.new {} block內的新變數則不會跟其他threads共享。另外還有一個特殊的方法,把thread instance當hash用:
複製內容到剪貼板
代碼:
outside = "DDDDD"
t1=Thread.new{
  puts outside # 得到DDDDD
  local_var = "AAAAA"
  Thread.current["var"] = "BBBBB"
}
puts t1["var"] # 得到BBBBB
puts local_var # 爆例外:未定義
以上就是一些ruby multi-threading的用法簡單說明,希望有幫助到multi-thread初學者,因為我自己也是XD

延伸閱讀:
參考資料 (英文,裡面還有講得更詳細)
Ruby多執行序範例(with AR)
Unknown error. System is going to shutdown.
關於我(簽到文)

TOP

這兩天被Thread搞了很多次,全部拋棄後問題反而就都沒有了||||主因是Ruby"模擬"thread,而非真實的thread,所以常出現很多很詭異的錯誤之類的,像是目前有碰到的轉檔抓檔轉資料庫,有的沒的問題一大票|||||一整個很糟糕的狀態就是了
(Plurk) 人因夢想而偉大,如果沒有信仰,則將一無所有,持續往殉道的路邁進,獻祭著自己的靈魂,走著最極端的路;而那迷霧的後面,會是地獄,也是天堂
self.attributes #=> [惡搞之魂,貓化身,怪咖吸鐵石,邪道程式設計師,動漫宅,蘿莉控,惡趣味,Geek,H=F^3]
[82,117,98,121,32,79,110,32,82,97,105,108,115,32,105,115,32,77,121,32,76,105,102,101].map{|l|l.chr}.to_s

TOP

ruby 的 multi thread的確是很麻煩的東西.
好險我之前寫的不太會有資料相干擾的情形,所以比較沒關係. :p
http://www.keane.idv.tw
http://www.upgreen.com

TOP

ruby 的 thread 問題從來都不是資料干擾問題,而是本身會掛點和運作不正確
(Plurk) 人因夢想而偉大,如果沒有信仰,則將一無所有,持續往殉道的路邁進,獻祭著自己的靈魂,走著最極端的路;而那迷霧的後面,會是地獄,也是天堂
self.attributes #=> [惡搞之魂,貓化身,怪咖吸鐵石,邪道程式設計師,動漫宅,蘿莉控,惡趣味,Geek,H=F^3]
[82,117,98,121,32,79,110,32,82,97,105,108,115,32,105,115,32,77,121,32,76,105,102,101].map{|l|l.chr}.to_s

TOP

如果掛點,然後a需要用到b的資料就完蛋啦.
我是指這個. :)
http://www.keane.idv.tw
http://www.upgreen.com

TOP

引用:
原帖由 lovingcatz 於 2010-7-12 10:04 發表
這兩天被Thread搞了很多次,全部拋棄後問題反而就都沒有了||||主因是Ruby"模擬"thread,而非真實的thread,所以常出現很多很詭異的錯誤之類的,...
如果用ruby的multi-thread拿來跑很重的運算或許會有你說的那些問題吧

我用的很單純…只是同時開幾個個thread去po噗浪回應,po完就終止了
…所以目前也沒出過狀況
Unknown error. System is going to shutdown.
關於我(簽到文)

TOP

發新話題