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>'

このコール スタックを構成するルールは何ですか? の 2 つのインスタンスが表示されます<main>。それらは何らかの形で組み合わされています。正確な方法はわかりません。また、複数のスレッドが実行されている場合はどうなりますか? 割り込みから呼び出されたコール スタックで結合または無視されるスレッドはどのように決定されますか?

4

1 に答える 1

0

あなたが探している「ルール」がわかりません。シグナルは非同期に受信され、Ruby ランタイムによってキューに入れられます。各プリミティブ実行ステップ (1.8 の AST ノード、YARV のバイトコード命令) の間で、ランタイムは保留中のシグナルがあるかどうかをチェックし、それらのバインドされたハンドラーを呼び出します。ハンドラーを呼び出しても、以前の既存の呼び出しスタックは変更されません。ハンドラーが戻った場合、プログラムの実行は中断したところから再開されます。

あなたの例で示されている実行フローは次のとおりです。メインでは、メインで定義されSignal.trapているブロックの処理を呼び出します。{d}次にa、を呼び出しbます。これは、cでc定義されたブロックを呼び出して永久にループします。{sleep(1)}sleep

SIGINT を送信すると、ランタイムがシグナルを受信し、INT ハンドラー ( test:7:in 'block in <main>')として登録したブロックを呼び出しdます。ef

ほとんどの時間はスリープ状態で費やされるため、INT ハンドラーが呼び出される可能性が最も高い実行ポイントです。ただし、INT シグナルが適切に受信された場合は、次の行の 1 つまたは両方が省略された同じコール スタックが表示されることがあります。

test:3:in `sleep'
test:3:in `block in c'
于 2012-10-22T06:54:41.177 に答える