當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Ruby Thread.handle_interrupt用法及代碼示例


本文簡要介紹ruby語言中 Thread.handle_interrupt 的用法。

用法

handle_interrupt(hash) { ... } → result of the block

更改異步中斷時序。

interrupt 表示異步事件和相應的過程,由 Thread#raise Thread#kill 、信號陷阱(尚不支持)和主線程終止(如果主線程終止,則所有其他線程將被殺死)。

給定的 hash 有像 ExceptionClass => :TimingSymbol 這樣的對。其中ExceptionClass 是給定塊處理的中斷。 TimingSymbol 可以是以下符號之一:

:immediate

立即調用中斷。

:on_blocking

BlockingOperation 時調用中斷。

:never

永遠不要調用所有中斷。

BlockingOperation表示該操作會阻塞調用線程,比如讀寫。在 CRuby 實現中,BlockingOperation 是在沒有 GVL 的情況下執行的任何操作。

被屏蔽的異步中斷被延遲,直到它們被啟用。此方法類似於 sigprocmask(3)。

NOTE

異步中斷很難使用。

如果需要線程間通信,請考慮使用另一種方式,例如 Queue

或者在對這種方法有深刻理解的情況下使用它們。

用法

在這個例子中,我們可以防止 Thread#raise 異常。

使用:never TimingSymbol RuntimeError 異常將始終在主線程的第一個塊中被忽略。在第二個 ::handle_interrupt 塊中,我們可以有目的地處理 RuntimeError 異常。

th = Thread.new do
  Thread.handle_interrupt(RuntimeError => :never) {
    begin
      # You can write resource allocation code safely.
      Thread.handle_interrupt(RuntimeError => :immediate) {
        # ...
      }
    ensure
      # You can write resource deallocation code safely.
    end
  }
end
Thread.pass
# ...
th.raise "stop"

雖然我們忽略了 RuntimeError 異常,但編寫我們的資源分配代碼是安全的。然後,確保塊是我們可以安全地釋放您的資源的地方。

保護 Timeout::Error

在下一個示例中,我們將防範 Timeout::Error 異常。這將有助於防止在正常確保子句期間發生 Timeout::Error 異常時泄漏資源。對於這個例子,我們使用標準庫 Timeout 的幫助,來自 lib/timeout.rb

require 'timeout'
Thread.handle_interrupt(Timeout::Error => :never) {
  timeout(10){
    # Timeout::Error doesn't occur here
    Thread.handle_interrupt(Timeout::Error => :on_blocking) {
      # possible to be killed by Timeout::Error
      # while blocking operation
    }
    # Timeout::Error doesn't occur here
  }
}

timeout 塊的第一部分,我們可以依賴 Timeout::Error 被忽略。然後在Timeout::Error => :on_blocking 塊中,任何將阻塞調用線程的操作都容易受到引發 Timeout::Error 異常的影響。

堆棧控製設置

可以堆疊多個級別的 ::handle_interrupt 塊,以便一次控製多個ExceptionClass 和TimingSymbol。

Thread.handle_interrupt(FooError => :never) {
  Thread.handle_interrupt(BarError => :never) {
     # FooError and BarError are prohibited.
  }
}

ExceptionClass 的繼承

將考慮從ExceptionClass 參數繼承的所有異常。

Thread.handle_interrupt(Exception => :never) {
  # all exceptions inherited from Exception are prohibited.
}

要處理所有中斷,請使用 Object 而不是 Exception 作為 ExceptionClass,因為 Exception 不處理終止/終止中斷。

相關用法


注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Thread.handle_interrupt。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。