Linuxでは、シグナルはどのように「配信」されますか?

Linuxでは、シグナルはどのように「配信」されますか?

Linuxシグナルを記述するために使用される用語は混乱しています。ほとんどのテキストでは、「信号がプロセスに渡されました」または「信号がスレッドに渡されました」と言います。

私が理解しているように、カーネルがそのハンドラを呼び出すと、シグナルはプロセス内のシグナルハンドラに「転送」されます。プロセス自体は非同期的に実行され、この「転送」プロセスはCPUが割り込みハンドラを呼び出すのと似ています。割り込みハンドラ(信号ハンドラ)はプロセススレッドでもなく、そのプロセスで実行されるスレッドでもありません。そうですか?カーネルによって開始される別のスレッドです。

したがって、シグナルはスレッドまたはプロセスに渡されるのではなく、プロセスに常駐し、特定のスレッドに必ずしも関連する必要はないシグナルハンドラに転送されます。これが間違っている場合、例えば、「信号がpthreadに渡される」という用語を正当化する信号ハンドラとpthreadの間の相関関係を教えてください。

ベストアンサー1

シグナルハンドラは、特定のプロセスのアドレス空間にある関数にすぎません。この機能は信号が受信されるたびに実行されます。これには特別なものはありません(一部の作業はシグナルハンドラで実行してはいけませんが)、特別なスレッドには存在しません。

信号はしばしばソフトウェア割り込みとして記述されますが、実際には非同期ではありません。*信号がプロセスに送信されると、カーネルはそれをプロセスの保留中の信号セットに追加します。すぐに何も起こりません。この信号は実際にはする次のコンテキストのすべてのエントリは再びユーザー空間に切り替わります(システムコールが返されるか、スケジューラがプロセスに切り替えます)。何らかの理由でプロセスがカーネルからユーザーに切り替えられない場合、シグナルは保留中のシグナルセットに残り、実行されません。

プロセスがシグナルハンドラを生成すると、カーネルに関数のアドレスを提供します。プロセスが信号を受信しようとすると、カーネル空間からユーザ空間への次のコンテキスト遷移は、プロセスがカーネルに入る前に持っていた実行コンテキストを復元しません。 (通常、コンテキストはカーネルに入ると保存され、カーネルを終了すると復元されます。)。代わりに、信号ハンドラの位置で実行を「再開」します。シグナルハンドラが返されると、呼び出しコードを実行します。rt_sigreturn()、復元されます。本物プロセスが中断された時点から続行できるようにする実行コンテキスト。

プロセスに複数のスレッドがある場合(つまり、特定のスレッドグループに複数のプロセスがある場合)、シグナルはスレッドグループのスレッドの1つにランダムに送信されます。これは、スレッドがメモリと他の多くのリソースを共有し、同じコードを実行することが多いためです。

*ハードウェアの観点からは非同期ではありませんが、ユーザー空間アプリケーションに関する限り、実際には非同期です。これが時々ソフトウェア割り込みと呼ばれる理由です。

†コンテキスト切り替えについて言及するときは特権を意味します。またはプロセスの切り替え(つまり、同じプロセス内のカーネルとユーザー間の簡単なモード切り替え、プロセスまたはカーネルスレッド間の「実際の」コンテキスト切り替え)

おすすめ記事