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)