Mechanizm sygnalizacji w jądrze Linux umożliwia uruchamianym aplikacjom asynchroniczne powiadamianie systemu o wystąpieniu nowego zdarzenia. Ze względu na swoją naturę ten mechanizm sygnalizacji jest ogólnie znany jako przerwania programowe. Podobnie jak przerwania sprzętowe, sygnały przerywają normalny przepływ aplikacji i nie można przewidzieć, kiedy aplikacja otrzyma sygnał.

Zanurzmy się głęboko w mechanizm sygnalizacji w Linuksie i zrozummy, co dzieje się za kulisami.

Podstawowe koncepcje dotyczące sygnałów w systemie Linux

W systemie Linux procesy generują sygnały w trzech podstawowych sytuacjach:

  • Gdy po stronie sprzętowej wystąpi sytuacja wyjątkowa. Na przykład możesz pomyśleć o zdarzeniach, takich jak aplikacja próbująca uzyskać dostęp do regionu poza dopuszczalna przestrzeń adresowa (błąd segmentacji) lub generowanie kodu maszynowego z dzieleniem przez zero operacja.
  • Sytuacje, takie jak użycie kombinacji klawiszy, takich jak Ctrl + C lub Ctrl + Z na konsoli przez użytkownika, zmieniając rozmiar ekranu konsoli lub wysyłając sygnał „kill”.
  • instagram viewer
  • Zegar ustawiony w aplikacji wygasa, limit procesora nadany aplikacji jest wysoki, dane przychodzą do otwartego deskryptora pliku itp.

Pojęcie sygnałów istnieje od wczesnych wersji Uniksa. Wcześniej istniało kilka różnic między wersjami Uniksa w zakresie przetwarzania sygnału. Później, z standaryzacja POSIX stworzony do zarządzania sygnałami, Linux i inne pochodne Uniksa zaczęły przestrzegać tych standardów. Z tego powodu koncepcje sygnałów Unix i sygnałów POSIX, które można napotkać w niektórych dokumentach, wskazują na różnice.

Numery sygnałów

Sygnały mają różne wartości liczbowe, zaczynając od jednej. Na przykład sygnał 1 to a HUP sygnał w prawie każdym systemie lub sygnał 9 to a ZABIĆ sygnał.

Jednak używanie tych liczb jest zdecydowanie odradzane, gdy używasz sygnałów w swoich aplikacjach. Dla sygnałów POSIX, sygnał.h plik powinien znajdować się w aplikacji, a programista powinien używać stałych definicji powiązanych liczb, takich jak ZGŁOSZENIE, SIGKILLitp. zamiast.

Jeśli zbadasz /usr/include/signal.h pliku w twoim systemie, możesz zobaczyć dodatkowe operacje i inne dołączone pliki, patrząc na definicje wartości, takie jak __USE_POSIX, __UŻYJ_XOPEN, __USE_POSIX199309itp. w pliku. Dostępne numery sygnałów w systemach Linux można znaleźć w /usr/include/asm-generic/signal.h plik, którego nie musisz umieszczać bezpośrednio w kodzie aplikacji.

Generowanie i wysyłanie sygnału

Generowanie sygnału następuje w wyniku zdarzenia. Jednak wysłanie (dostarczenie) sygnału do odpowiedniej aplikacji nie następuje jednocześnie z generowaniem sygnału.

Aby sygnał został wysłany do aplikacji, aplikacja musi być aktualnie uruchomiona i posiadać zasoby procesora. Dlatego wysłanie sygnału do określonej aplikacji następuje, gdy po zmianie kontekstu dana aplikacja ponownie zacznie działać.

Koncepcja Oczekującego Sygnału

W czasie od wygenerowania do wysłania sygnału sygnały są w stanie czuwania. Możesz uzyskać dostęp do liczby oczekujących sygnałów i liczby oczekujących sygnałów dozwolonych dla procesu z /proc/PID/status plik.

# Dla procesu z PID: 2299
kot /proc/2299/status

# Wyjście
...
SigQ: 2/31630
...

Maski i blokowanie sygnału

Dokładny czas nadejścia sygnałów jest często nieprzewidywalny przez aplikację. Dlatego podczas każdej operacji mogą wystąpić pewne krytyczne przerwy. Może to powodować poważne problemy w przypadku aplikacji na dużą skalę.

Aby zapobiec takim niepożądanym sytuacjom, konieczne jest stosowanie masek sygnałowych. W ten sposób możliwe jest zablokowanie niektórych sygnałów przed krytyczną operacją. Na tym etapie ważne jest, aby ukończyć część krytyczną i usunąć zdefiniowane bloki. Ten proces jest czymś, na co programista aplikacji powinien zwrócić uwagę.

Gdy aplikacja zablokuje sygnał, inne wygenerowane sygnały tego samego typu będą w stanie oczekiwania na odblokowanie. W aplikacji wysyłanie oczekujących sygnałów jest również zapewnione, gdy tylko blokada zostanie usunięta.

W ten sposób te same typy sygnałów zawieszonych w momencie zablokowania są wysyłane do aplikacji tylko raz po usunięciu blokady podczas normalnego użytkowania. Sytuacja wygląda inaczej w przypadku sygnałów czasu rzeczywistego.

Typy sygnałów systemu Linux

Domyślne działania mogą się różnić w zależności od typu sygnału. Jeśli aplikacja, która odbiera odpowiedni sygnał, nie ma funkcji obsługi sygnału, wykonywana jest akcja domyślna. Czasami oznacza to zamknięcie aplikacji, a czasami zignorowanie sygnału.

Niektórych sygnałów nie można przechwycić w warstwie aplikacji, sygnały te zawsze wykonują domyślną akcję (jak sygnał KILL).

Oprócz niektórych działań, które powodują zamknięcie aplikacji, tworzony jest również plik zrzutu pamięci. Pliki zrzutu rdzenia, utworzone przez zapisanie tabeli pamięci wirtualnej powiązanego procesu na dysk, pomagają użytkownika do sprawdzenia informacji o stanie przed zakończeniem procesu za pomocą narzędzi debugowania w kolejnych etapach.

Poniższe wartości są oparte na przykładowa architektura MIPS:

Sygnał Numer Akcja domyślna Czy można go złapać?
ZGŁOSZENIE 1 Zakończ aplikację TAk
PODPIS 2 Zakończ aplikację TAk
WYJDŹ 3 Zakończ aplikację (zrzut pamięci) TAk
SIGILL 4 Zakończ aplikację (zrzut pamięci) TAk
SIGTRAP 5 Zakończ aplikację (zrzut pamięci) TAk
SIGABRT 6 Zakończ aplikację (zrzut pamięci) TAk
SIGFPE 8 Zakończ aplikację (zrzut pamięci) TAk
SIGKILL 9 Zakończ aplikację Nie
SIGBUS 10 Zakończ aplikację (zrzut pamięci) TAk
SIGSEGV 11 Zakończ aplikację (zrzut pamięci) TAk
SIGSYS 12 Zakończ aplikację (zrzut pamięci) TAk
SIGPIPE 13 Zakończ aplikację TAk
SIGALRM 14 Zakończ aplikację TAk
SIGTERM 15 Zakończ aplikację TAk
SIGUSR1 16 Zakończ aplikację TAk
SIGUSR2 17 Zakończ aplikację TAk
SIGCHLD 18 Ignorować TAk
SIGTSTP 20 Zatrzymaj się TAk
SIGURG 21 Ignorować TAk
SIGPOLL 22 Zakończ aplikację TAk
SIGSTOP 23 Zatrzymaj się Nie
SYGKONT 25 Kontynuuj, jeśli się zatrzymałeś TAk
PODPIS 26 Zatrzymaj się TAk
SIGTTOU 27 Zatrzymaj się TAk
SIGVTALRM 28 Zakończ aplikację TAk
SIGPROF 29 Zakończ aplikację TAk
SIGXCPU 30 Zakończ aplikację (zrzut pamięci) TAk
SIGXFSZ 31 Zakończ aplikację (zrzut pamięci) TAk

Cykl życia sygnałów w systemie Linux

Sygnały przechodzą przez trzy etapy. Są one wytwarzane głównie w fazie produkcji, przez jądro lub dowolny proces i są reprezentowane przez liczbę. Działają lekko i szybko, ponieważ nie obciążają ich dodatkowo. Ale jeśli spojrzysz na stronę POSIX, zobaczysz, że sygnały czasu rzeczywistego mogą przesyłać dodatkowe dane.

Faza dostawy sygnałów następuje po fazie produkcji. Zwykle sygnały docierają do aplikacji z jądra tak szybko, jak to możliwe. Czasami jednak aplikacje mogą blokować sygnały podczas wykonywania krytycznych operacji. W takich przypadkach sygnał pozostaje w toku do momentu zawarcia transakcji.

Podobnie jak sygnały, procesy są również integralną częścią ekosystemu Linuksa. Zrozumienie, czym są procesy i jak działają, jest kluczowe, jeśli planujesz zostać administratorem systemu Linux.

Czym jest proces w Linuksie?

Czytaj dalej

DzielićĆwierkaćDzielićE-mail

Powiązane tematy

  • Linux
  • Jądro Linuksa
  • Administracja systemu

O autorze

Fatih Küçükkarakurt (9 opublikowanych artykułów)

Inżynier i programista, pasjonat matematyki i technologii. Zawsze lubił komputery, matematykę i fizykę. Opracował projekty silników gier, a także uczenie maszynowe, sztuczne sieci neuronowe i biblioteki algebry liniowej. Ponadto kontynuuje prace nad uczeniem maszynowym i macierzami liniowymi.

Więcej od Fatiha Küçükkarakurt

Zapisz się do naszego newslettera

Dołącz do naszego newslettera, aby otrzymywać porady techniczne, recenzje, bezpłatne e-booki i ekskluzywne oferty!

Kliknij tutaj, aby zasubskrybować