killall
よりも穏やかな方法で、同じ名前のすべてのプロセスを終了するにはどうすればよいですか?プロセスを中断したくありませんが、適切に終了する時間を残してください。
こちらもご覧ください:
システムモニターでは、Kill ProcessとEnd Processの違いは何ですか?
killall
はデフォルトでSIGTERM
を送信します。これは、alreadyであり、アプリケーションが自分でクリーンアップする機会を残すニースのアプローチです。 「今すぐ死ぬ!」アプローチはSIGKILL
シグナルを送信することで、killall
のオプションとして指定する必要があります。から GNU Cライブラリ:終了シグナル :
マクロ:intSIGTERM
[...]通常の方法で、pollylyプログラムに終了を要求します。
GNOMEシステムモニターに関する質問にリンクします。それは、その「プロセスの終了」アクションにもSIGTERM
を使用します(そして、私はその質問に対する答えに矛盾していることに気付きます)。あなた自身を確認するためにソースコードでそれを見つけることができます:
<item>
<attribute name="label" translatable="yes">_End</attribute>
<attribute name="action">win.send-signal-end</attribute>
<attribute name="accel"><Primary>e</attribute>
<attribute name="target" type="i">15</attribute>
</item>
ここの15はシグナル番号です。信号15はSIGTERM
です。また、システムモニターは、他の質問が尋ねられて回答されるかなり前にSIGTERM
を使用しています。
git blame
のGithub表現を調べて、GNOMEシステムモニターのソースコードで信号がどのように記述されるかについて行われた変更を以下に示します。
83007f2 2013年7月24日GActionパラメータを使用して信号を送信するための重複コードを置換
e766b2d 2013年7月18日GActionへのポート処理ポップアップメニュー
97674c79 2012年10月3日ProcData構造体を取り除きます
8c5296c 2011年7月3日ソースファイル全体でインデントを統一します。
これらはいずれもSIGQUIT
からSIGTERM
に変更されておらず、最後の質問はリンクされた質問が行われる前のものでした。
@hvdによる答えは基本的に正しいです。それをさらにバックアップするために、init
プロセスは、コンピューターをシャットダウンするときに最初にSIGTERM
をプロセスに送信し、その後、まだ終了していない場合は遅延後にSIGKILL
を送信します。プロセスはSIGKILL
を処理/無視できません。
しかし、もう少し詳しく説明すると、本当の答えは、プログラムがそれを処理していることを確実に知る方法がないということです。 SIGTERM
は、プログラムの終了を丁寧に要求するために使用する最も一般的なシグナルですが、すべてのシグナル処理は、プログラムがシグナルで何かを行うことに依存します。
別の言い方をすれば、他の回答に基づいて、@ Josまたは@AlexGregで作成されたプログラムがある場合、おそらくSIGQUIT
を処理しますが、SIGTERM
を処理しないため、SIGTERM
を送信することはSIGQUIT
よりも「ソフト」ではありません。
あなたが自分でそれをいじることができるように、私はいくつかのコードを書きました。以下をsignal-test.c
として保存してから、
gcc -o signal-test signal-test.c
その後、./signal-test
を実行して、killall -s <signal>
で異なる信号を送信するとどうなるかを確認できます。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
現状では、コードはSIGTERMとSIGQUITの両方を適切に処理します。行signal(SIG...
をコメントアウトして(行の先頭で//
を使用して)シグナルハンドラーを削除してから、実行して再度シグナルを送信できます。これらの異なる出力を見ることができるはずです:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
信号を処理するかどうかによって異なります。
シグナルを無視してみることもできます:
signal(SIGTERM, SIG_IGN);
それを行ってからSIGTERM
を送信しても何も行われない場合は、SIGKILL
を使用してプロセスを終了する必要があります。
詳細はman 7 signal
にあります。この方法でsignal()
を使用することは、移植性がないと見なされることに注意してください-代替手段よりもずっと簡単です!
もう1つの小さな脚注-Solarisではkillall
はすべてのプロセスを強制終了しようとします。それらのすべて。 rootで実行すると驚くかもしれません:)
「すべて終了」はkillall -s SIGQUIT [process name]
になります。おしゃれなソリューションが必要な場合は、alias endall='killall -s SIGQUIT'
を定義してください。