Як я можу вбити певну нитку процесу?


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або тому, що вбити просто, не в змозі вбити окремих процесів.

Відповіді:


26

Нитки є невід’ємною частиною процесу і не можуть бути вбиті поза ним. Існує функція pthread_kill, але вона застосовується лише в контексті самого потоку. З документів за посиланням:

Зауважте, що pthread_kill () викликає обробку сигналу лише в контексті заданого потоку; дія сигналу (припинення або зупинка) впливає на процес в цілому.


+1. просто додати сюди. в процесі ви можете використовувати pthread_kill () для передачі сигналів в окремий потік. Ви можете додати якийсь обробник сигналу, який це робить.
Хемант

@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.