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>. 它们以某种方式结合在一起。我不完全确定如何。另外,当有多个线程运行时会发生什么?如何确定在从中断调用的调用堆栈中合并或忽略哪些线程?

4

1 回答 1

0

我不确定你在寻找什么“规则”。信号由 ruby​​ 运行时异步接收并排队;在每个原始执行步骤(1.8 中的 AST 节点,YARV 中的字节码指令)之间,运行时检查是否有未决信号并为它们调用绑定的处理程序。调用处理程序不会修改先前存在的调用堆栈。如果您的处理程序要返回,程序执行将重新从中断处重新开始。

这是您的示例展示的执行流程:在 main 中,您调用Signal.trap将它交给{d}main 中定义的块。然后你调用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'
于 2012-10-22T06:54:41.177 回答