本文簡要介紹ruby語言中 Thread類
的用法。
線程是並發編程模型的 Ruby 實現。
需要多個執行線程的程序非常適合 Ruby 的 Thread
類。
例如,我們可以使用 ::new
創建一個獨立於主線程執行的新線程。
thr = Thread.new { puts "What's the big deal" }
然後我們可以暫停主線程的執行並允許我們的新線程完成,使用 join
:
thr.join #=> "What's the big deal"
如果我們在主線程終止之前不調用thr.join
,那麽包括thr
在內的所有其他線程都將被殺死。
或者,您可以使用數組同時處理多個線程,如下例所示:
threads = []
threads << Thread.new { puts "What's the big deal" }
threads << Thread.new { 3.times { puts "Threads are fun!" } }
創建幾個線程後,我們等待它們全部連續完成。
threads.each { |thr| thr.join }
要檢索線程的最後一個值,請使用 value
thr = Thread.new { sleep 1; "Useful value" }
thr.value #=> "Useful value"
Thread
初始化
為了創建新線程,Ruby 提供了 ::new
、 ::start
和 ::fork
。必須為這些方法中的每一個提供一個塊,否則將引發 ThreadError
。
當子類化 Thread
類時,您的子類的 initialize
方法將被 ::start
和 ::fork
忽略。否則,請務必在 initialize
方法中調用 super。
Thread
終止
對於終止線程,Ruby 提供了多種方法來執行此操作。
類方法 ::kill
旨在退出給定線程:
thr = Thread.new { sleep }
Thread.kill(thr) # sends exit() to thr
或者,您可以使用實例方法 exit
或其任何別名 kill
或 terminate
。
thr.exit
Thread
狀態
Ruby 提供了一些實例方法來查詢給定線程的狀態。要獲取具有當前線程狀態的字符串,請使用 status
thr = Thread.new { sleep }
thr.status # => "sleep"
thr.exit
thr.status # => false
您還可以使用 alive?
來判斷線程是在運行還是在休眠,並使用 stop?
來判斷線程是死了還是休眠。
Thread
變量和範圍
由於線程是使用塊創建的,因此相同的規則適用於變量範圍的其他 Ruby 塊。在這個塊中創建的任何局部變量隻能由這個線程訪問。
Fiber-local 與線程本地
每根光纖都有自己的存儲桶用於 Thread#[]
存儲。當您設置新的 fiber-local 時,它隻能在此 Fiber
中訪問。為了顯示:
Thread.new {
Thread.current[:foo] = "bar"
Fiber.new {
p Thread.current[:foo] # => nil
}.resume
}.join
此示例使用 []
獲取和 []=
設置fiber-locals,您還可以使用 keys
列出給定線程的fiber-locals,並使用 key?
檢查是否存在fiber-local。
對於thread-locals,它們可以在線程的整個範圍內訪問。給定以下示例:
Thread.new{
Thread.current.thread_variable_set(:foo, 1)
p Thread.current.thread_variable_get(:foo) # => 1
Fiber.new{
Thread.current.thread_variable_set(:foo, 2)
p Thread.current.thread_variable_get(:foo) # => 2
}.resume
p Thread.current.thread_variable_get(:foo) # => 2
}.join
您可以看到線程局部的:foo
轉移到光纖中,並在線程結束時更改為2
。
此示例使用 thread_variable_set
來創建新的thread-locals,並使用 thread_variable_get
來引用它們。
還有 thread_variables
列出所有thread-locals,還有 thread_variable?
來檢查給定的線程本地是否存在。
Exception
處理
當線程內部引發未處理的異常時,它將終止。默認情況下,此異常不會傳播到其他線程。異常被存儲,當另一個線程調用 value
或 join
時,異常將在該線程中重新引發。
t = Thread.new{ raise 'something went wrong' }
t.value #=> RuntimeError: something went wrong
可以使用 Thread#raise
實例方法從線程外部引發異常,該方法采用與 Kernel#raise
相同的參數。
設置 Thread.abort_on_exception
= true、 Thread#abort_on_exception
= true 或 $DEBUG = true 將導致線程中引發的後續未處理異常在主線程中自動重新引發。
通過添加類方法 ::handle_interrupt
,您現在可以使用線程異步處理異常。
調度
Ruby 提供了幾種方法來支持程序中的調度線程。
第一種方法是使用類方法 ::stop
,使當前運行的線程進入休眠狀態並安排另一個線程的執行。
一旦線程休眠,您可以使用實例方法 wakeup
將您的線程標記為符合調度條件。
您也可以嘗試 ::pass
,它嘗試將執行傳遞給另一個線程,但取決於操作係統是否正在運行的線程會切換。 priority
也是如此,它允許您向線程調度程序提示在傳遞執行時要優先處理哪些線程。此方法也取決於操作係統,在某些平台上可能會被忽略。
相關用法
- Ruby Thread.kill用法及代碼示例
- Ruby Thread.pending_interrupt?用法及代碼示例
- Ruby Thread kill()用法及代碼示例
- Ruby Thread add_trace_func用法及代碼示例
- Ruby ThreadError類用法及代碼示例
- Ruby Thread.report_on_exception用法及代碼示例
- Ruby Thread.group用法及代碼示例
- Ruby Thread abort_on_exception用法及代碼示例
- Ruby Thread terminate()用法及代碼示例
- Ruby Thread.list用法及代碼示例
- Ruby Thread.ignore_deadlock =用法及代碼示例
- Ruby Thread.stop用法及代碼示例
- Ruby Thread.abort_on_exception=用法及代碼示例
- Ruby Thread.stop?用法及代碼示例
- Ruby Thread.new用法及代碼示例
- Ruby Thread.report_on_exception=用法及代碼示例
- Ruby ThreadGroup.add用法及代碼示例
- Ruby ThreadGroup.list用法及代碼示例
- Ruby Thread.value用法及代碼示例
- Ruby Thread.run用法及代碼示例
- Ruby Thread exit()用法及代碼示例
- Ruby Thread backtrace_locations()用法及代碼示例
- Ruby Thread.thread_variables用法及代碼示例
- Ruby Thread.thread_variable?用法及代碼示例
- Ruby Thread.thr[sym]用法及代碼示例
注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Thread類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。