Как я могу убить определенную нить процесса?


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

Это показывает процесс mypс PID = 797 и четырьмя потоками с разными SPID.

Как я могу убить определенную нить процесса, не убивая весь процесс. Я понимаю, что это может быть невозможно вообще в некоторых случаях, когда существуют фатальные зависимости от этого конкретного потока. Но возможно ли это в любом случае? Да, как?

Я попытался, kill 799и сам процесс был прекращен. Теперь я не уверен, что это произошло из-за того, что были зависимости, которые mypпотерпели неудачу без процесса 800или потому, что kill просто не в состоянии уничтожить отдельные процессы.

Ответы:


26

Потоки являются неотъемлемой частью процесса и не могут быть уничтожены вне его. Есть функция pthread_kill, но она применяется только в контексте самого потока. Из документов по ссылке:

Обратите внимание, что pthread_kill () вызывает обработку сигнала только в контексте данного потока; действие сигнала (завершение или остановка) влияет на процесс в целом.


+1. просто чтобы добавить сюда. в процессе вы можете использовать pthread_kill () для отправки сигналов в отдельный поток. может быть, вы можете добавить обработчик сигнала, который это делает.
Hemant

@hemant: Предположим, MS Word использует отдельный поток для проверки орфографии. Убийство этой нити не должно привести к разрушению всего этого, если оно не спроектировано таким образом. Почему процесс не может существовать без этого потока в подобных ситуациях?
Лазер

1
Что ж, я полагаю, вы могли бы спроектировать модель потоков, которая была бы независимой от родительского процесса, но позволяла внешним процессам уничтожать внутрипроцессные потоки, но при этом открывалась куча червей в отношении безопасности, управления процессами и целостности системы, которая мне не нужна. Я думаю, что любой разработчик системы охотно подчинится. Потоки достаточно сложны без таких головных болей. Уничтожение потока изнутри не является проблемой, потому что работа выполняется родительским процессом, который несет ответственность за возникшие проблемы и может быть уничтожен - автоматически или иным образом.
gvkv

«если он не спроектирован таким образом»: основная причина использования потоков именно для того, чтобы вы могли совместно использовать ресурсы. Это скорее как сбить половину дома.
pjc50

2
@Lazer, один поток не может проверить орфографию одновременно с тем, как другой поток обновляет текст, потому что вы печатаете. Из-за этого для создания фоновой проверки орфографии он должен сделать что-то вроде захвата блокировки, чтобы предотвратить изменение текста другим потоком, создать копию некоторых слов, снять блокировку, а затем проверить скопированные слова в задний план. Если вам случится убить его, пока он удерживал блокировку, вы бы повесили другой поток, как только попытаетесь набрать текст. Многопоточные приложения полны взаимозависимостей, подобных этой.
psusi

6

Канонический ответ на этот вопрос: при сотрудничестве процесса, каким бы механизмом он ни был обеспечен. Без сотрудничества процесса это невозможно. То, что процесс состоит из потоков, является внутренней деталью процесса, которая по преднамеренному замыслу не раскрывается вне процесса.


А как насчет отправки других сигналов из командной строки?
yucer

@yucer Я не уверен, что понимаю, о чем ты спрашиваешь.
Дэвид Шварц

Я имею в виду отправку другого сигнала из списка, показанного как «kill -l». Я ищу способ отдать команду конкретному потоку для выгрузки трассировки стека, чтобы увидеть, что он делает.
Юсер

@yucer Это будет зависеть от платформы. Некоторые из них предоставляют способ дать команду конкретному потоку сбросить стек. Лично я обнаружил, что проще использовать скрипт, чтобы присоединить отладчик (например gdb) к процессу, дать команду всем потокам сбросить стек и затем отсоединить.
Дэвид Шварц

1

Помимо ответа @ gkv, вы можете взглянуть на функцию pthread_cancel(3), часть <pthread.h>. Со страницы руководства:

Функция pthread_cancel () отправляет запрос отмены потоку потока. То, когда и когда целевой поток реагирует на запрос отмены, зависит от двух атрибутов, которые находятся под контролем этого потока: его состояние и тип отмены.


1

Вы можете найти tgkill () полезным. Это специфично для Linux, как упоминается на странице руководства.

tgkill () отправляет сигнал sig потоку с идентификатором потока tid в группе потоков tgid. (Напротив, kill (2) может использоваться только для отправки сигнала процессу (то есть группе потоков) в целом, и сигнал будет доставлен в произвольный поток внутри этого процесса.)


Это не относится к вопросу о том, как убить поток, а не о том, как отправить сигнал потоку.
Дэвид Шварц
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.