Como posso matar um segmento específico de um processo?

21
$ ps -e -T | grep myp | grep -v grep
  797   797 ?        00:00:00 myp
  797   798 ?        00:00:00 myp
  797   799 ?        00:00:00 myp
  797   800 ?        00:00:00 myp

Isso mostra o processo mypcom PID = 797 e quatro threads com diferentes SPIDs.

Como posso matar um segmento específico do processo sem matar todo o processo. Entendo que talvez não seja possível em alguns casos quando houver dependências fatais nesse segmento específico. Mas, é possível em qualquer caso? Sim, como?

Eu tentei kill 799e o processo em si foi encerrado. Agora, não tenho certeza de que isso ocorreu porque houve dependências que mypfalharam sem o processo 800ou porque o kill é simples e não é capaz de matar processos individuais.

lazer
fonte

Respostas:

26

Threads são parte integrante do processo e não podem ser eliminados fora dele. Existe a função pthread_kill , mas ela se aplica apenas ao contexto do próprio encadeamento. Dos documentos no link:

Observe que pthread_kill () apenas faz com que o sinal seja tratado no contexto do encadeamento especificado; a ação do sinal (término ou parada) afeta o processo como um todo.

gvkv
fonte
+1. apenas para adicionar aqui. dentro do processo, você pode usar pthread_kill () para enviar sinais para threads individuais. pode ser que você possa adicionar algum manipulador de sinal que faça isso.
Hemant
@ hemant: Suponha que o MS Word use um thread separado para verificação ortográfica. Matar esse fio não deve derrubar tudo, a menos que seja projetado dessa maneira. Por que o processo não pode existir sem esse segmento em situações como essas?
Lazer
1
Bem, suponho que você possa projetar um modelo de encadeamento para ser independente de um processo pai, mas permitir que processos externos matem encadeamentos intraprocessos, mas isso abre uma lata de worms com relação à segurança, gerenciamento de processos e integridade do sistema que eu não uso. acho que qualquer projetista de sistemas se submeteria voluntariamente. Rosquear já é difícil o suficiente sem esse tipo de dor de cabeça. Matar um encadeamento a partir do interior não é um problema, porque o trabalho é realizado pelo processo pai, que é responsabilizado se surgir algum problema e puder ser eliminado - automaticamente ou não.
gvkv
"a menos que seja projetado dessa maneira": o principal motivo para o uso de threads é exatamente para que você possa compartilhar recursos. É como derrubar meia casa.
Pjc50
2
@Lazer, um tópico não pode verificar a ortografia ao mesmo tempo que outro tópico está atualizando o texto porque você está digitando. Por esse motivo, para ter um encadeamento de verificação ortográfica em segundo plano, ele deve fazer algo como agarrar um cadeado para impedir que o outro encadeamento altere o texto, fazer uma cópia de algumas das palavras, soltar o cadeado e verificar as palavras copiadas no fundo. Se você o matasse enquanto ele mantinha a trava, penduraria o outro segmento assim que tentasse digitar. Os aplicativos multithread estão cheios de interdependências como esta.
Psusi
6

A resposta canônica para essa pergunta é: Com a cooperação do processo, por qualquer mecanismo que ele forneça. Sem a cooperação do processo, é impossível. O fato de o processo consistir em encadeamentos é um detalhe interno do processo que, por design intencional, não é exposto fora do processo.

David Schwartz
fonte
E quanto ao envio dos outros sinais da linha de comando?
yucer
@yucer Não sei se entendi o que você está perguntando.
David Schwartz
Quero dizer, enviando outro sinal da lista mostrada por "kill -l". Estou procurando uma maneira de comandar um segmento específico para despejar o rastreamento de pilha para ver o que está fazendo.
yucer
@yucer Isso será específico da plataforma. Alguns fornecem uma maneira de comandar um segmento específico para despejar a pilha. Pessoalmente, achei mais fácil usar um script para anexar um depurador (como gdb) ao processo, comandar todos os threads para despejar a pilha e desanexar.
David Schwartz
1

Além da resposta do @ gkv, você pode dar uma olhada na função pthread_cancel(3), parte de <pthread.h>. Na página do manual:

A função pthread_cancel () envia uma solicitação de cancelamento ao thread do thread. Se e quando o thread de destino reage à solicitação de cancelamento depende de dois atributos que estão sob o controle desse thread: seu estado e tipo de cancelabilidade.

Ivan P
fonte
1

Você pode achar tgkill () útil. É específico do Linux, como a página de manual menciona.

tgkill () envia o sinal sig para o thread com o ID do thread tid no grupo de threads tgid. (Por outro lado, kill (2) só pode ser usado para enviar um sinal para um processo (ou seja, grupo de encadeamentos) como um todo, e o sinal será entregue a um encadeamento arbitrário nesse processo.)

Amit
fonte
Isso não aborda a questão sobre como matar um thread, não como enviar um sinal para um thread.
David Schwartz