web-dev-qa-db-ja.com

`Sl`プロセスを強制終了できないのはなぜですか?

Lubuntu 18.04では、pcmanfmを開きます

$ pcmanfm . 

pcmanfmの現在のディレクトリの下にあるイメージファイルのサムネイルを確認した後、Alt-F4でpcmanfmのウィンドウを閉じましたが、ターミナルエミュレーターではフォアグラウンドでまだハングしています。

Ctrl-Zとbg 2で背景に移動して強制終了しましたが、動作しません。

$ jobs -l 
[2]+ 31124 Running                 pcmanfm . &
$ kill %2
$ jobs -l
[2]+ 31124 Running                 pcmanfm . &
$ Sudo kill 31124
$ jobs -l
[2]+ 31124 Running                 pcmanfm . &

その状態はSlで、Sは「割り込み可能なスリープ(イベントの完了を待機)」を意味し、lは「マルチスレッド(NPTL pthreadのようにCLONE_THREADを使用)であることを意味します)」では、なぜプロセスを強制終了できないのでしょうか。どうやって殺すの?ありがとう。

$ ps aux | grep [3]1124
t        31124  0.8  0.7 693952 57064 pts/9    Sl   06:34   0:47 pcmanfm 

5
Tim

デフォルトでは、killはTERMシグナルのみを送信します。何らかの理由でpcmanfmはこのシグナルを無視しています。オプション-KILLを渡して強制終了すると、シグナルがスケジューラーに送信され、プロセスは削除され、クリーンアップまたはアピールの機会がなくなります。

あなたはしないでください自分が所有しているプロセスをkillするには、追加の特権(Sudo)が必要です。 Sudoは危険な場合があります。欲求不満で使用しないでください。

17
ctrl-alt-delor

デフォルトでは、killはSIGTERMを送信します。これはプロセスのシグナルハンドラーによって処理され、プロセスは次のことができます。

  • 何もしないシグナルハンドラをインストールする
  • 信号を無視する
  • 信号をマスクします(マスクを解除すると配信されます)

pcmanfmはそのようなことをしていると思います。後者の2つは、/proc/PID/statusSigBlk、およびSigIgnで確認できます。

一方、SIGKILL(9)はプロセス自体では処理されず、シグナルハンドラーを変更したり、無視したり、マスクしたりすることはできません。

pcmanfnのpidに対してこのpython3プログラムを実行して、プログラムが無視またはブロックするものを正確に確認してください(python 3.5が必要):

#!/usr/bin/python3

import os
import sys
import time
import signal

def show(label, value):
    ivalue = int(value, 16)
    print("%s: %s:"% (label, value.strip()), end=' ')
    cnt=1
    while ivalue:
        if ivalue & 1:
            print("%s(%s)" % (signal.Signals(cnt).name, cnt), end=' ')
        ivalue>>=1
        cnt+=1
    print()

if len(sys.argv)==1:
    pid=os.getpid()
else:
    pid=int(sys.argv[1])

status=open('/proc/%d/status' % (pid,)).readlines()
print("Pid: %d" % (pid,))
for line in status:
    what, value = line.split(':', 1)
    if what=='SigBlk':
        show('Blocked', value)
    Elif what=='SigIgn':
        show('Ignored', value)

SIGTERMがそこにあるかどうかを確認できるはずです。

4
V13