Как убить отдельный поток под процессом в Linux?

13

введите описание изображения здесь

Это отдельные потоки процесса получения пакетов. Есть ли способ убить какой-то отдельный поток? Предоставляет ли Linux какую-либо конкретную команду, которая может уничтожить или отправить сигнал остановки любому конкретному потоку в процессе?

Д-р Kawsaruzzaman
источник
Какая у вас программа Packet Reciever? (У меня его нет на рабочем столе Debian) Пожалуйста, расскажите подробнее, возможно, предоставьте некоторую ссылку. Так что отредактируйте свой вопрос, чтобы улучшить.
Старынкевич
1
Я думаю, вы не понимаете, что сигнал «стоп» останавливает процесс, независимо от того, в какой поток вы его отправляете.
Дэвид Шварц
1
Присоедините с помощью GDB и убейте нить , затем отсоедините.
Мартин
1
@ Md.Kawsaruzzaman Это просто не сработает. Предположим, например, что поток находится в середине выделения памяти и удерживает блокировку распределителя памяти. Если вы остановите поток, он никогда не снимет блокировку, и в конце концов другие потоки тоже остановятся. Что бы вы ни пытались сделать, это не способ сделать это. (Может случиться так, что вы захотите остановить работу, выполняемую этим потоком. Но для этого вам нужно сотрудничество процесса. Если это не дает возможности сделать это, это невозможно).
Дэвид Шварц
1
Также обратите внимание, что на вашем скриншоте каждый «поток» имеет отдельный PID. Я не уверен, что вы могли бы даже предназначаться для отдельных потоков, поскольку сигналы могли быть посланы только процессам.
Сзальски

Ответы:

16

Обычно убивать отдельный поток из более крупного процесса довольно опасно. Эта тема может:

  • Изменять некоторые общие состояния с другими потоками, которые могут быть повреждены
  • Держите некоторую блокировку, которая никогда не освобождается, в результате чего блокировка становится бесконечно недоступной
  • ... или любое количество других вещей, которые могут привести к неправильной работе других потоков.

В целом, помимо управления и синхронизации самим приложением, нет смысла убивать отдельные потоки.

Крис Даун
источник
5
Это не полезно вообще. ОП спрашивает, как убить поток, а не должен ли он или нет.
Мартин
То, что я хочу, это процесс, чтобы убить или остановить любой конкретный поток для какой-то цели. Я предполагаю, что из-за какой-то ошибки, иногда наш приемник автоматически отключается. Мы находим причины, поскольку программа разрабатывается нашими собственными разработками. Теперь дело в том, что некоторые потоки могут автоматически закрываться. Мы протестировали со стороны кода и получили , что ребенок нить независимы , но со стороны сервера все еще получают несколько потоков вниз иногда , которые вызывают общий процесс , чтобы закрыть тоже ..
. Md Kawsaruzzaman
12

Вы можете использовать tgkill (2) или tkillв своей C-программе (вам нужно использовать syscall (2) ), но вы не хотите . Внутри вашей программы вы можете использовать pthread_kill (3), что редко бывает полезно.

(Я точно не знаю, какой эффект будет иметь tgkillили tkill- например, с SIGKILLили SIGTERM- на поток)

Библиотека pthreads (7) использует низкоуровневые вещи (включая некоторые signal (7) -s и futex (7) -s и т. Д.; См. Также nptl (7) ), и если вы убили raw (с помощью tkillили tgkill) В отдельном потоке ваш процесс будет в неправильном состоянии (так что неопределенное поведение ), потому что какой-то внутренний инвариант будет нарушен.

Поэтому изучите документацию вашей программы приема пакетов и найдите другой способ. Если это свободное программное обеспечение , изучите его исходный код и улучшите его.

Прочитайте более внимательно сигнал (7) и сигнал безопасности (7) . Сигналы предназначены для отправки в процессы ( kill (2) ) и обработки в потоках.

И на практике сигналы и потоки плохо сочетаются. Прочитайте некоторый учебник .

Обычная хитрость, когда кодируете многопоточную программу (и хотите обрабатывать внешние сигналы, такие как SIGTERM), это использовать канал (7) для вашего собственного процесса и опрашивать (2) этот канал в каком-то другом потоке (вы также можете рассмотреть Linux конкретный signalfd (2) ), с помощью устройства для записи сигнала, записать (2) -байт байта или нескольких из них в этот канал. Этот хорошо известный трюк хорошо объяснен в документации Qt (и вы можете использовать его в своей собственной программе, даже без Qt).

Василий Старынкевич
источник
4
tgkillФункция не дает никакой возможности прекратить поток. Он отправляет сигнал в поток. Он называется «убить», потому что это исторический способ уничтожения процесса, и его нельзя использовать для уничтожения потока.
Дэвид Шварц
Я предполагаю, что отправка SIGKILLветки вредит. Или это всегда убивает весь процесс? А как насчет SIGTERM? Кстати, даже если причинен вред только потоку, я хочу сказать, что процесс находится в ужасном состоянии.
Старынкевич
5
Да, SIGKILLи SIGTERMсигналы определены, чтобы убить или завершить процесс. Это верно независимо от того, какой поток их получает - они все равно означают одно и то же. Прекращение потока без тесного сотрудничества с его процессом будет дерьмовым выстрелом и, вероятно, будет катастрофическим для процесса.
Дэвид Шварц