2012-10-22 181 views
1

caller內容在中斷內呼叫的規則是什麼?當我運行下面的代碼:中斷呼叫者

File: test 

1| def a; b end 
2| def b; c end 
3| def c; loop{sleep(1)} end 
4| def d; e end 
5| def e; f end 
6| def f; puts caller; exit end 
7| Signal.trap("INT"){d} 
8| a 
執行期間

,並鍵入Ctrl+c,我得到下面的輸出:

test:5:in `e' 
test:4:in `d' 
test:7:in `block in <main>' 
test:3:in `call' 
test:3:in `sleep' 
test:3:in `block in c' 
test:3:in `loop' 
test:3:in `c' 
test:2:in `b' 
test:1:in `a' 
test:8:in `<main>' 

什麼是構成此調用堆棧中的規則?我看到兩個<main>的實例。它們以某種方式結合在一起。我不確定如何。另外,當有多個線程運行時會發生什麼?如何確定從中斷調用的調用堆棧中組合或忽略哪些線程?

回答

0

我不確定你要找什麼「規則」。信號是由ruby運行時異步接收和排隊的;在每個基本執行步驟(1.8中的AST節點,YARV中的字節碼指令)之間,運行時檢查是否存在掛起信號併爲它們調用綁定處理程序。調用處理程序不會修改先前的現有調用堆棧。如果您的處理程序要返回,那麼程序執行會在它停止的地方再次啓動。

下面是您的示例所展示的執行流程:主要的是,您可以撥打Signal.trap,將它交給一個在main中定義的塊{d}。然後,您撥打a,調用b,調用c,它永遠循環調用c {sleep(1)}中定義的塊,該塊調用sleep

您發送SIGINT和運行時接收到信號,並調用你註冊爲INT處理器(test:7:in 'block in <main>'),其中要求d,它調用e,它調用f,打印您看到調用堆棧並退出該塊。

由於大部分時間都是在睡眠中度過的,所以這是INT處理程序被調用的最有可能的執行點。但是,如果INT信號恰到好處,您可能會看到省略了其中一條或兩條線的相同調用堆棧:

test:3:in `sleep' 
test:3:in `block in c'