kill -9をプロセスに送信する場合、プロセスの協力(シグナルの処理など)は必要ありません。単にプロセスを強制終了します。
一部の信号はキャッチされ無視される可能性があるため、すべての信号に協力が必要であると思われます。しかしごとにman 2 signal
、「シグナル SIGKILLとSIGSTOPはキャッチまたは無視することはできません」。SIGTERMをキャッチできるため、プレーンkill
が常に有効であるとは限りません。一般的に、これはプロセスのハンドラーで何かがおかしくなったことを意味します。1
プロセスが特定のシグナルのハンドラーを定義しない(またはできない)場合、カーネルはデフォルトのアクションを実行します。 SIGTERMとSIGKILLの場合、これはプロセスを終了します(PIDが1でない限り、カーネルは終了しませんinit
)2 ファイルハンドルが閉じられ、メモリがシステムプールに返され、親がSIGCHILDを受信し、孤立していることを意味します子はinitなどによって呼び出されたように継承されますexit
(を参照man 2 exit
)。プロセスはもはや存在しません-ゾンビとして終わらない限り、その場合、それはまだいくつかの情報とともにカーネルのプロセステーブルにリストされています。それは、その親がwait
この情報を適切に処理します。ただし、ゾンビプロセスにはメモリが割り当てられていないため、実行を継続できません。
Linuxがプロセスによって使用されるすべてのリソースへの参照を保持し、プロセスを「殺す」ときにLinuxがそのテーブルを通過してリソースを1つずつ解放する、メモリ内のグローバルテーブルのようなものはありますか?
これで十分だと思います。物理メモリはページ(通常は4 KBチャンクに等しい1ページ)ごとに追跡され、それらのページはグローバルプールから取得され、グローバルプールに返されます。ページに含まれるデータ(つまり、既存のファイルから読み取られたデータ)が再び必要になった場合に、一部の解放されたページがキャッシュされるという点で少し複雑です。
マンページは「シグナル」について述べていますが、確かにそれは単なる抽象化です。
もちろん、すべての信号は抽象化されています。それらは「プロセス」のような概念的なものです。私は少しセマンティクスをプレイしていますが、SIGKILLがSIGTERMと質的に異なるという意味であれば、yesとnoです。それは捕まえられないという意味ではありますが、両方ともシグナルであるという意味ではありません。類推により、リンゴはオレンジではありませんが、リンゴとオレンジは、先入観によると、両方の果物です。SIGKILL はキャッチできないため、より抽象的なように見えますが、それでもシグナルです。SIGTERM処理の例を次に示します。これらは以前に見たことがあると思います。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
このプロセスは永久にスリープ状態になります。ターミナルで実行し、SIGTERMで送信できますkill
。次のようなものを吐き出します:
Received 15 from pid 25331, uid 1066.
1066は私のUIDです。PID kill
は、実行元のシェルのPID、またはフォークした場合はkillのPIDになります(kill 25309 & echo $?
)。
繰り返しますが、SIGKILLのハンドラーを設定しても意味がありません。3私の場合kill -9 25309
、プロセスは終了します。しかし、それはまだシグナルです。カーネルは、送信者に関する情報を持っている信号の種類、信号それは、など
1.可能な信号のリストをまだ見ていない場合は、を参照してくださいkill -l
。
2.別の例外は、Tim Postが以下で言及するように、無停電スリープ中のプロセスに適用されます。これらは根本的な問題が解決されるまで起こせないので、すべてのシグナル(SIGKILLを含む)がその期間延期されます。ただし、プロセスはそのような状況を意図的に作成することはできません。
3.これはkill -9
、実際に使用する方が良いことを意味するものではありません。私の例のハンドラーはそれに通じないという意味で悪いものexit()
です。SIGTERMハンドラーの本当の目的は、プロセスに一時ファイルのクリーンアップなどの処理を実行し、自発的に終了する機会を与えることです。を使用する場合kill -9
、このチャンスは得られないので、「自発的に終了する」部分が失敗したと思われる場合にのみ、それを行ってください。
kill -9
参照。