Jak zabić pojedynczy wątek w procesie w systemie Linux?

13

wprowadź opis zdjęcia tutaj

Są to poszczególne wątki procesu odbierania pakietów. Czy jest jakiś sposób na zabicie pojedynczego wątku? Czy Linux udostępnia jakieś konkretne polecenie, które może zabić lub wysłać sygnał stop do dowolnego konkretnego wątku w trakcie procesu?

Md. Kawsaruzzaman
źródło
Jaki jest twój program do odbierania pakietów? (Nie mam go na pulpicie Debiana) Proszę powiedzieć więcej, być może podać link. Więc edytować swoje pytanie do poprawy.
Basile Starynkevitch,
1
Myślę, że nie zdajesz sobie sprawy, że sygnał „stop” zatrzymuje proces, niezależnie od wątku, do którego go wysyłasz.
David Schwartz,
1
Dołącz za pomocą GDB i zabij wątek , a następnie odłącz.
Martin
1
@ Md.Kawsaruzzaman To po prostu nie zadziała. Załóżmy na przykład, że wątek znajduje się w środku alokacji pamięci i trzyma blokadę w alokatorze pamięci. Jeśli zatrzymasz nić, to nigdy nie zwolni blokady i ostatecznie inne wątki też się zatrzymają. Cokolwiek próbujesz zrobić, nie jest to właściwy sposób. (Być może chcesz zatrzymać pracę wykonywaną przez wątek. Ale potrzebujesz współpracy procesu, aby to zrobić. Jeśli nie da się tego zrobić, nie da się tego zrobić.)
David Schwartz
1
Pamiętaj również, że na twoim zrzucie ekranu każdy „wątek” ma osobny PID. Nie jestem pewien, czy mógłbyś nawet celować w oddzielne wątki, ponieważ sygnały mogą być wysyłane tylko do procesów.
szalski

Odpowiedzi:

16

Zasadniczo zabicie pojedynczego wątku z większego procesu jest dość niebezpieczne. Ten wątek może:

  • Modyfikuj część stanu współdzielonego za pomocą innych wątków, które mogą ulec uszkodzeniu
  • Trzymaj blokadę, która nigdy się nie uwalnia, co powoduje, że blokada staje się nieskończenie niedostępna
  • ... lub dowolną liczbę innych rzeczy, które mogą powodować błędy w innych wątkach.

Ogólnie rzecz biorąc, poza zarządzaniem i synchronizacją przez samą aplikację, zabijanie pojedynczych wątków nie ma sensu.

Chris Down
źródło
5
To w ogóle nie jest przydatne. OP pyta, jak zabić wątek, a nie czy powinien.
Martin
To, czego chcę, to proces zabicia lub zatrzymania określonego wątku w jakimś celu. Zakładam, że z powodu jakiegoś błędu czasami nasz odbiornik wyłącza się automatycznie. Znajdujemy przyczyny, ponieważ program jest opracowywany przez nasz własny dział badań i rozwoju. Rzecz w tym, że niektóre wątki mogą być automatycznie zamykane. Przetestowaliśmy od strony kodu i upewniliśmy się, że wątek potomny jest niezależny, ale po stronie serwera wciąż występują pewne wątki, co powoduje, że cały proces również się wyłącza ..
Md. Kawsaruzzaman
12

Możesz użyć tgkill (2) lub tkillw swoim programie C (musisz użyć syscall (2) ), ale nie chcesz . Z poziomu programu możesz użyć pthread_kill (3) - co jest rzadko przydatne.

(Nie wiem dokładnie, jaki efekt miałby tgkilllub tkill- np. Z SIGKILLlub SIGTERM- na wątek)

Biblioteka pthreads (7) używa rzeczy niskiego poziomu (w tym niektórych sygnałów (7) i futex (7) -s itp.; Patrz także nptl (7) ) i jeśli zabiłeś na surowo (z tkilllub tgkill) niektóre w pojedynczym wątku proces byłby w złym stanie (tak niezdefiniowane zachowanie ), ponieważ niektóre wewnętrzne niezmienniki zostałyby zepsute.

Więc przestudiuj dokumentację swojego programu odbierającego pakiety i znajdź inny sposób. Jeśli jest to wolne oprogramowanie , przestudiuj jego kod źródłowy i popraw go.

Czytaj dalej ostrożnie sygnał (7) i bezpieczeństwo sygnału (7) . Sygnały mają być wysyłane do procesów (przez kill (2) ) i obsługiwane w wątkach.

A w praktyce sygnały i wątki nie pasują dobrze. Przeczytaj samouczek pthread .

Powszechną sztuczką podczas kodowania programu wielowątkowego (i chcącego obsługiwać zewnętrzne sygnały, takie jak SIGTERM) jest użycie potoku (7) do własnego procesu i odpytywanie (2) tego potoku w innym wątku (możesz również rozważyć Linuksa specyficzne signalfd (2) ), z handeriem sygnału zapisz (2) - bajt lub kilka z nich do tej potoku. Ta dobrze znana sztuczka jest dobrze wyjaśniona w dokumentacji Qt (i możesz jej użyć we własnym programie, nawet bez Qt).

Basile Starynkevitch
źródło
4
Ta tgkillfunkcja nie umożliwia zakończenia wątku. Wysyła sygnał do wątku. Nazywa się to „kill”, ponieważ jest historycznym sposobem na zabicie procesu i nie można go użyć do zabicia wątku.
David Schwartz,
Wydaje mi się, że wysłanie SIGKILLwątku szkodzi mu. A może zawsze zabija cały proces? A co SIGTERM? BTW, nawet jeśli tylko wątek zostanie uszkodzony, mam na myśli to, że proces jest w fatalnym stanie.
Basile Starynkevitch,
5
Tak, sygnały SIGKILLi SIGTERMsą zdefiniowane w celu zabicia lub zakończenia procesu. Jest to prawdą niezależnie od tego, jaki wątek je otrzymuje - nadal oznaczają to samo. Zakończenie wątku bez ścisłego współdziałania jego procesu byłoby bzdurą i prawdopodobnie katastrofalne dla procesu.
David Schwartz,