W systemach POSIX sygnały kończące mają zwykle następującą kolejność (zgodnie z wieloma stronami MAN i specyfikacją POSIX):
SIGTERM - uprzejmie poproś o zakończenie procesu. Zakończy się z wdzięcznością, czyszcząc wszystkie zasoby (pliki, gniazda, procesy potomne itp.), Usuwając pliki tymczasowe i tak dalej.
SIGQUIT - silniejsza prośba. Zakończy bez gracji, nadal czyści zasoby, które absolutnie wymagają oczyszczenia, ale może nie usunie plików tymczasowych, może zapisuje gdzieś informacje debugowania; w niektórych systemach zostanie również zapisany zrzut rdzenia (niezależnie od tego, czy sygnał zostanie przechwycony przez aplikację, czy nie).
SIGKILL - najsilniejsza prośba. Proces nie jest nawet proszony o zrobienie czegokolwiek, ale system oczyści proces, czy tak będzie, czy nie. Najprawdopodobniej zapisywany jest zrzut pamięci.
Jak SIGINT pasuje do tego obrazu? Proces CLI jest zwykle przerywany przez SIGINT, gdy użytkownik trafi na CRTL + C, jednak proces w tle może być również zakończony przez SIGINT przy użyciu narzędzia KILL. To, czego nie widzę w specyfikacjach lub plikach nagłówkowych, to to, czy SIGINT jest mniej lub bardziej skuteczny niż SIGTERM lub czy w ogóle istnieje różnica między SIGINT i SIGTERM.
AKTUALIZACJA:
Najlepszy opis sygnałów kończących, jaki do tej pory znalazłem, znajduje się w dokumentacji GNU LibC . Wyjaśnia bardzo dobrze, że istnieje zamierzona różnica między SIGTERM a SIGQUIT.
Mówi o SIGTERM:
To normalny sposób, aby uprzejmie poprosić program o zakończenie.
I mówi o SIGQUIT:
[...] i tworzy zrzut pamięci po zakończeniu procesu, tak jak sygnał błędu programu. Można o tym myśleć jako o stanie błędu programu „wykrytym” przez użytkownika. [...] Podczas obsługi SIGQUIT najlepiej pomijać pewne rodzaje porządków. Na przykład, jeśli program tworzy pliki tymczasowe, powinien obsłużyć inne żądania zakończenia, usuwając pliki tymczasowe. Ale lepiej, aby SIGQUIT ich nie usuwał, aby użytkownik mógł je sprawdzić w połączeniu ze zrzutem jądra.
SIGHUP jest również wystarczająco dobrze wyjaśniony. SIGHUP nie jest tak naprawdę sygnałem zakończenia, oznacza po prostu "utratę połączenia" z użytkownikiem, więc aplikacja nie może oczekiwać, że użytkownik odczyta dalsze dane wyjściowe (np. Wyjście stdout / stderr) i nie ma żadnych danych wejściowych, których można oczekiwać od użytkownika już. W przypadku większości aplikacji oznacza to, że lepiej zakończyć. Teoretycznie aplikacja może również zdecydować, że przechodzi w tryb demona po odebraniu SIGHUP i działa teraz jako proces w tle, zapisując dane wyjściowe do skonfigurowanego pliku dziennika. W przypadku większości demonów, które już działają w tle, SIGHUP zwykle oznacza, że powinny ponownie przeanalizować swoje pliki konfiguracyjne, więc po edycji plików konfiguracyjnych należy wysłać je do procesów w tle.
Jednak na tej stronie nie ma żadnego użytecznego wyjaśnienia SIGINT, poza tym, że jest on wysyłany przez CRTL + C. Czy jest jakiś powód, dla którego ktoś miałby traktować SIGINT inaczej niż SIGTERM? Jeśli tak, jaki byłby to powód i jak zmieniłaby się obsługa?
sudo fuser -l
w wierszu poleceń. Dla mnie to wywołuje:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
uzyskać listę sygnałów.Odpowiedzi:
SIGTERM i SIGKILL są przeznaczone do ogólnych żądań „zakończenia tego procesu”. SIGTERM (domyślnie) i SIGKILL (zawsze) spowodują zakończenie procesu. SIGTERM może zostać przechwycony przez proces (np. Aby mógł wykonać własne czyszczenie, jeśli chce) lub nawet całkowicie zignorowany; ale SIGKILL nie może zostać złapany ani zignorowany.
SIGINT i SIGQUIT są przeznaczone specjalnie dla żądań z terminala: określone znaki wejściowe mogą być przypisane do generowania tych sygnałów (w zależności od ustawień sterowania terminalu). Domyślną akcją dla SIGINT jest ten sam rodzaj zakończenia procesu, co domyślna akcja dla SIGTERM i niezmienna akcja dla SIGKILL; domyślną akcją dla SIGQUIT jest również zakończenie procesu, ale mogą wystąpić dodatkowe działania zdefiniowane w ramach implementacji, takie jak generowanie zrzutu pamięci. W razie potrzeby proces może je złapać lub zignorować.
SIGHUP, jak powiedziałeś, ma na celu wskazanie, że połączenie terminala zostało utracone, a nie być sygnałem zakończenia jako takim. Ale znowu, domyślną akcją dla SIGHUP (jeśli proces go nie wychwytuje lub zignoruje) jest zakończenie procesu w taki sam sposób jak SIGTERM itp.
W definicjach POSIX znajduje się tabela,
signal.h
która zawiera listę różnych sygnałów oraz ich domyślnych działań i celów, a rozdział Ogólny interfejs terminala zawiera dużo więcej szczegółów na temat sygnałów związanych z terminalami.źródło
Jak zauważył DarkDust, wiele sygnałów daje te same wyniki, ale procesy mogą przypisywać im różne działania, rozróżniając sposób generowania każdego sygnału. Patrząc na kod źródłowy jądra FreeBSD (kern_sig.c) widzę, że oba sygnały są obsługiwane w ten sam sposób, przerywają proces i są dostarczane do dowolnego wątku.
źródło
man 7 signal
Jest to wygodna, nienormatywna strona podręcznika projektu Linux man-pages , na której często chcesz szukać informacji o sygnałach Linuksa.
Wersja 3.22 wspomina o interesujących rzeczach, takich jak:
i zawiera tabelę:
która podsumowuje sygnał,
Action
który odróżnia np. SIGQUIT od SIGQUIT, ponieważ SIGQUIT ma akcjęCore
i SIGINTTerm
.Działania są udokumentowane w tym samym dokumencie:
Nie widzę żadnej różnicy między SIGTERM i SIGINT z punktu widzenia jądra, ponieważ oba mają akcję
Term
i można je złapać. Wydaje się, że jest to tylko „powszechne rozróżnienie według konwencji użytkowania”:kill
Niektóre sygnały są zgodne z ANSI C, a inne nie
Istotna różnica polega na tym, że:
Są one opisane w sekcji „7.14 Obsługa sygnałów” projektu C99 N1256 :
co sprawia, że SIGINT jest dobrym kandydatem do interaktywnego Ctrl + C.
POSIX 7
POSIX 7 dokumentuje sygnały z
signal.h
nagłówkiem: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlTa strona zawiera również następującą tabelę zainteresowań, która wymienia niektóre rzeczy, które już widzieliśmy
man 7 signal
:BusyBox init
Domyślne
reboot
polecenie BusyBox 1.29.2 wysyła SIGTERM do procesów, usypia na sekundę, a następnie wysyła SIGKILL. Wydaje się, że jest to powszechna konwencja w różnych dystrybucjach.Gdy zamykasz system BusyBox za pomocą:
wysyła sygnał do procesu init.
Następnie program obsługi sygnału inicjującego kończy wywołanie:
który drukuje na terminal:
Oto minimalny, konkretny przykład .
Sygnały wysyłane przez jądro
źródło
Po szybkim wyszukiwaniu w Google sigint vs sigterm wygląda na to, że jedyną zamierzoną różnicą między nimi jest to, czy zostało zainicjowane przez skrót klawiaturowy, czy przez jawne wywołanie
kill
.W rezultacie możesz na przykład przechwycić sigint i zrobić z nim coś specjalnego, wiedząc, że prawdopodobnie został wysłany przez skrót klawiaturowy. Może odświeży ekran lub coś w tym stylu, zamiast umierać (niezalecane, ponieważ ludzie oczekują
^C
zabicia programu, tylko przykład).Dowiedziałem się też, że
^\
należy wysłać sigquit, którego sam mogę zacząć używać. Wygląda na bardzo przydatne.źródło
Używając
kill
(zarówno wywołania systemowego, jak i narzędzia, możesz wysłać prawie każdy sygnał do dowolnego procesu, pod warunkiem, że masz pozwolenie. Proces nie może rozróżnić, jak powstał sygnał i kto go wysłał.To powiedziawszy, SIGINT naprawdę ma zasygnalizować przerwanie Ctrl-C, podczas gdy SIGTERM jest ogólnym sygnałem końcowym. Nie ma koncepcji, że sygnał byłby "silniejszy", z jedynym wyjątkiem, że istnieją sygnały, których nie można zablokować ani obsłużyć (SIGKILL i SIGSTOP, zgodnie ze stroną podręcznika).
Sygnał może być tylko „silniejszy” niż inny sygnał w odniesieniu do tego, jak proces odbierający obsługuje sygnał (i jakie jest domyślne działanie dla tego sygnału). Na przykład, domyślnie zarówno SIGTERM, jak i SIGINT prowadzą do zakończenia. Ale jeśli zignorujesz SIGTERM, nie zakończy on twojego procesu, podczas gdy SIGINT nadal to robi.
źródło
Z wyjątkiem kilku sygnałów, programy obsługi sygnałów mogą przechwytywać różne sygnały lub można zmodyfikować domyślne zachowanie po otrzymaniu sygnału. Zobacz
signal(7)
stronę podręcznika, aby uzyskać szczegółowe informacje.źródło
SIGINT
(" przerwanie programu ") jest wysyłany, gdy użytkownik wpisze znak INTR (normalnieC-c
)." „SIGINT 2 Term Interrupt from keyboard” Naciśnięcie Ctrl-C,SIGINT
zostanie wysłane. Proces zwykle umiera. Co więcej dać?