Por que não posso matar um processo 'Sl'?

5

No Lubuntu 18.04, abro o pcmanfm

$ pcmanfm . 

e depois de olhar para as miniaturas dos arquivos de imagem sob o diretório atual no pcmanfm, eu fechei a janela do pcmanfm por Alt-F4, mas ainda está pendurado no primeiro plano no emulador de terminal.

Eu movo para o plano de fundo por Ctrl-Z e bg 2 e mato, mas não funciona.

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

Seu estado é Sl , S significa "sleep interrompível (esperando que um evento seja concluído)" e l significa "é multiencadeado (usando CLONE_THREAD, como o NPTL pthreads faz)". Então eu me pergunto por que não posso matar o processo? Como você mataria isso? Obrigado.

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

.

    
por Tim 05.11.2018 / 14:05

2 respostas

17

Por padrão, kill apenas envia um sinal TERM , por algum motivo pcmanfm está ignorando este sinal. Se você passar a opção -KILL para kill, ele enviará o sinal para o agendador e o processo será removido sem chance de limpar ou apelar.

Você não precisa de privilégios extras ( sudo ) para matar os processos que você possui. sudo pode ser perigoso, não use apenas por frustração.

    
por 05.11.2018 / 14:11
4

kill por padrão envia SIGTERM. Isso é tratado pelo manipulador de sinal do processo e o processo pode:

  • instala um manipulador de sinal que simplesmente não faz nada
  • tem um sinal ignorado
  • mascare o sinal (e faça a entrega assim que for desmascarado)

Eu acho que pcmanfm faz algo assim. Você pode encontrar os dois últimos observando /proc/PID/status , em SigBlk e SigIgn

SIGKILL (9), por outro lado, não é tratado pelo próprio processo e não pode ter seu manipulador de sinal alterado, ser ignorado ou ser mascarado.

Tente executar este programa python3 contra o pid de pcmanfn para ver exatamente o que ele ignora ou bloqueia (precisa do 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)

Você deve ser capaz de ver se o SIGTERM está lá.

    
por 06.11.2018 / 02:05