回答:
kill -9
(SIGKILL)プロセスを強制終了する許可があれば、常に機能します。基本的に、プロセスはsetuidまたはsetgidではなく、ユーザーが開始するか、rootでなければなりません。例外が1つあります。ルートでさえ、致命的なシグナルをPID 1(init
プロセス)に送信できません。
ただし、すぐkill -9
に動作するとは限りません。SIGKILLを含むすべてのシグナルは非同期に配信されます。カーネルはそれらの配信に時間がかかる場合があります。通常、信号の配信には最大で数マイクロ秒かかり、ターゲットがタイムスライスを取得するのにかかる時間だけです。ただし、ターゲットがシグナルをブロックしている場合、ターゲットがブロックを解除するまでシグナルはキューに入れられます。
通常、プロセスはSIGKILLをブロックできません。しかし、カーネルコードは、システムコールを呼び出すときにカーネルコードを実行できます。カーネルコードは、システムコールを中断すると、カーネル内のどこかで、またはより一般的には一部のカーネル不変式に違反する不正なデータ構造になる場合、すべての信号をブロックします。したがって、(バグまたは設計ミスのために)システムコールが無期限にブロックされる場合、プロセスを強制終了する方法は事実上ない可能性があります。(ただし、システムコールを完了すると、プロセスは強制終了されます。)
システムコールでブロックされたプロセスは、割り込み不可能なスリープ状態です。ps
またはtop
コマンドが(ほとんどのUnix上の)状態でそれを表示しますD
(本来は「用のD ISK」、私は思います)。
長く中断できないスリープの古典的なケースは、サーバーが応答しないときにNFS経由でファイルにアクセスするプロセスです。最近の実装ではintr
、割り込み不能なスリープを強制しない傾向があります(たとえば、Linuxでは、マウントオプションにより、NFSファイルアクセスを中断する信号が許可されます)。
または、出力でマークされたZ
(またはH
Linuxでは区別がわからない)エントリが表示されることがあります。これらは技術的にはプロセスではなく、ゾンビプロセスであり、プロセステーブル内のエントリにすぎず、親プロセスに子プロセスの死を通知できるように保持されます。親プロセスが注意を払う(または死ぬ)と、それらは消えます。ps
top
man 5 nfs
:「 カーネル2.6.25以降、intr
/ nointr
mountオプションは非推奨です。これらのカーネルで保留中のNFS操作を中断できるのはSIGKILLのみです。指定されている場合、このマウントオプションは無視され、古いカーネルとの後方互換性を提供します。」
sshfs
プロセスを強制終了できます(他のFUSEファイルシステムでも同様です。この方法でいつでも強制的にアンマウントできます)。
いつかプロセスが存在し、次の理由で強制終了できません。
top
でZtop
にDによってシグナルが送られます。手がかりについては、/var/log/kern.log
および/var/log/dmesg
(または同等のもの)を確認してください。私の経験では、NFSマウントのネットワーク接続が突然切断されたか、デバイスドライバーがクラッシュした場合にのみ、これが発生しました。ハードドライブがクラッシュした場合にも発生する可能性があると思います。
lsof
プロセスが開いているデバイスファイルを確認するために使用できます。
kill -9
通常、60分待っても機能しませんでした。唯一の解決策は再起動することでした。
@ Maciejと@ Gillesの回答で問題が解決せず、プロセスを認識できない場合(そして、ディストリビューションに何があるのかを尋ねても答えは返されません)。ルートキットおよび所有されている他の兆候を確認します。ルートキットは、プロセスの強制終了を防ぐことができるだけではありません。実際、多くの人はあなたがそれらを見ることを防ぐことができます。しかし、1つの小さなプログラムを変更するのを忘れると、それらは発見される可能性があります(たとえば、変更されますがtop
、変更されませんhtop
)。ほとんどの場合、これは事実ではありませんが、申し訳ありませんが安全です。
キルとは、実際にはシグナルを送信することを意味します。送信できる信号は複数あります。kill -9は特別なシグナルです。
信号を送信するとき、アプリケーションはそれを処理します。そうでない場合、カーネルはそれを扱います。そのため、アプリケーションで信号をトラップできます。
しかし、キル-9は特別だと言いました。アプリケーションが取得できないという点で特別です。カーネルに直接送られ、最初の可能な機会にアプリケーションを本当に強制終了します。言い換えれば、死んでしまう
kill -15は、シグナル終了を表すシグナルSIGTERMを送信します。言い換えると、アプリケーションに終了を指示します。これは、シャットダウンする時間であることをアプリケーションに伝える簡単な方法です。ただし、アプリケーションが応答しない場合、kill -9がそれを殺します。
kill -9が機能しない場合は、おそらくカーネルが正常に動作していないことを意味します。再起動が必要です。今まで起こったことを思い出せません。
まず、そのゾンビプロセスかどうかを確認します(非常に可能です)。
ps -Al
次のようなものが表示されます。
0 Z 1000 24589 1 0 80 0 - 0 exit ? 00:00:00 soffice.bin <defunct>
(左側の「Z」に注意してください)
5番目の列が1でない場合、親プロセスがあることを意味します。 その親プロセスIDを強制終了してみてください。
PPID = 1の場合、それを殺さないでください!! 、他のどのデバイスまたはプロセスがそれに関連する可能性があるかを考えます。
たとえば、マウントされたデバイスまたはサンバを使用していた場合は、アンマウントしてみてください。それはゾンビプロセスを解放するかもしれません。
注:(ps -Al
またはtop
)に「Z」ではなく「D」が表示される場合は、リモートマウント(NFSなど)に関連している可能性があります。私の経験では、再起動がそこに行く唯一の方法ですが、そのケースをより詳細にカバーする他の答えを確認することができます。
他の人が述べたように、無停電睡眠のプロセスはすぐに(または、場合によっては)強制終了できません。特定のシナリオ、特にプロセスがNFSで待機している一般的なケースでこの問題を解決するために、別のプロセス状態TASK_KILLABLEが追加されたことは注目に値します。http://lwn.net/Articles/288056/を参照してください
残念ながら、これはカーネル以外ではNFS以外では使用されていないと思います。
ls
アクセスするプロセスsshfs
を強制終了できませんでした。FUSEまたはsshfsの解決策はありますか?将来的にそのような状況を回避するために使用できますか?2.6.30カーネル
私がたくさん見てくれた小さなスクリプトを作成しました!
これを使用して、パスに指定された名前のプロセスを強制終了できます(これに注意してください!!)。または、「-u username」パラメーターを使用して、特定のユーザーのプロセスを強制終了できます。
#!/bin/bash
if [ "$1" == "-u" ] ; then\n
PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
echo "############# Killing all processes of user: $2 ############################"
else
echo "############# Killing processes by name: $1 ############################"
processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi
for process in $processes ; do
# "command" stores the entire commandline of the process that will be killed
#it may be useful to show it but in some cases it is counter-productive
#command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
echo "Killing process: $process"
echo ""
kill -9 $process
done
この種の問題がありました。これは、+で起動しstrace
て中断したプログラムでした。最終的に(トレースまたは停止)状態になりました。どのように起こったのか正確にはわかりませんが、で殺すことはできませんでした。Ctrl
C
T
SIGKILL
簡単に言えば、私はそれを殺すことに成功しましたgdb
:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
gillesの答えからの手がかりに基づいて、<defunct>
システムリソースを使用している(ps単位で)「Z」とマークされたプロセスがあり、リッスンしているポートが開いていて、そのポートに接続できました。これは、それを実行した後でしたkill -9
。その親は "1"(つまりinit
)だったので、理論的には繰り返して消える必要があります。しかし、そうではありませんでした。走ってはいませんでしたが、「死にかけていません」
私の場合、それはゾンビでしたが、それでもリソースを消費しています... FWIW。
そして、それは、任意の数のことでkillableではなかったkill -9
の
そして、その親はinit
そうでしたが、刈り取られていませんでした(クリーンアップ)。すなわちinit
、ゾンビの子供がいました。
また、問題を解決するために再起動する必要はありませんでした。再起動は問題を回避するために「機能するはず」でしたが、シャットダウンを高速化しました。ただ優雅ではない、それはまだ可能でした。
そして、それはゾンビプロセスが所有するLISTENポートでした(およびlocalhostをlocalhostに接続するCLOSE_WAITステータスのような他のポートもいくつかありました)。そして、それでも接続を受け入れました。ゾンビとしても。まだポートをクリーンアップするようにはなっていないので、受け入れられる機会はありませんでしたが、着信接続はまだTCPリスニングポートのバックログに追加されました。
上記の多くは、インターウェブのさまざまな場所で「不可能」と言われています。
返されるまでに数時間かかっていた「システムコール」(この例ではioctl)を実行している内部スレッドがあったことが判明しました(これは予期された動作でした)。どうやら、システムは、ioctl
呼び出しから戻るまでプロセスを「ずっと」強制終了することはできません。数時間後に戻ってきて、物事は片付けられ、ソケットはすべて自動的に閉じられました。それは死刑囚の苦しい時間です!カーネルはそれを殺すのを辛抱強く待っていました。
だから、OPに答えるために、時にはあなたは待たなければならない。長い間。その後、殺害は最終的にかかります。
また、dmesgをチェックして、カーネルパニック(カーネルバグ)があったかどうかを確認します。