Sygnały
Asynchroniczne powiadomienia
Sygnały to bezpłatna lekcja C Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C Academy zawiera 4 lekcji w sumie.
Czym jest sygnał
Sygnał to asynchroniczne powiadomienie wysyłane do procesu w celu poinformowania go o wystąpieniu zdarzenia, takiego jak naciśnięcie przez użytkownika klawiszy Ctrl-C lub zakończenie procesu potomnego. Sygnały są lekką formą IPC.
Typowe sygnały
Kilka sygnałów, z którymi często się Państwo spotkają:
SIGINTprzerwanie (Ctrl-C)SIGTERMuprzejma prośba o zakończenie procesuSIGKILLwymuszone zakończenie (nie można go przechwycić)SIGCHLDproces potomny zmienił stanSIGSEGVnieprawidłowy dostęp do pamięci
Domyślne działania
Każdy sygnał ma domyślne działanie: zakończenie procesu, zakończenie procesu ze zrzutem pamięci, zignorowanie, zatrzymanie lub kontynuowanie. Większość z tych działań można zastąpić własnym handlerem.
Instalowanie handlera
Nowoczesnym i przenośnym sposobem ustawienia handlera jest użycie sigaction. Handler to funkcja przyjmująca numer sygnału.
#include <signal.h>
#include <stdio.h>
void on_signal(int sig) {
/* note: printf is not async-signal-safe; for demo only */
write(1, "caught\n", 7);
}
int install(void) {
struct sigaction sa = {0};
sa.sa_handler = on_signal;
return sigaction(SIGINT, &sa, NULL);
}Dlaczego nie signal()
Stara funkcja signal() zachowuje się różnie w zależności od systemu (resetowanie handlera, brak kontroli nad SA_RESTART). Należy preferować sigaction, które ma jasno określone i przenośne działanie.
Funkcje bezpieczne asynchronicznie względem sygnałów
Handler może przerwać kod w dowolnym momencie, dlatego wolno mu wywoływać tylko funkcje bezpieczne asynchronicznie względem sygnałów, takie jak write. Wywołanie z handlera funkcji printf lub malloc grozi zakleszczeniem albo uszkodzeniem danych.
Używanie flagi volatile
Bezpieczny wzorzec polega na tym, że handler ustawia flagę typu volatile sig_atomic_t, a główna pętla ją sprawdza. Dzięki temu handler pozostaje krótki i bezpieczny.
#include <signal.h>
volatile sig_atomic_t stop = 0;
void handler(int sig) {
stop = 1; /* only set a flag */
}
/* main loop: while (!stop) { do_work(); } */Wysyłanie sygnałów
Użyj kill(pid, sig), aby wysłać sygnał do innego procesu, albo raise(sig), aby wysłać go do siebie. Mimo swojej nazwy funkcja kill wysyła dowolny sygnał, a nie tylko sygnały kończące proces.
#include <signal.h>
int notify(int pid) {
return kill(pid, SIGTERM); /* ask process to terminate */
}Blokowanie sygnałów
Aby chronić sekcję krytyczną, tymczasowo blokuj sygnały za pomocą sigprocmask i zbioru sygnałów. Zablokowane sygnały pozostają oczekujące i zostaną dostarczone po ich odblokowaniu.
#include <signal.h>
void block_int(void) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_BLOCK, &set, NULL);
}Zbieranie procesów potomnych za pomocą SIGCHLD
Gdy proces potomny kończy działanie, jądro wysyła sygnał SIGCHLD. Handler wywołujący waitpid zbiera zakończony proces, zapobiegając pozostawaniu w tabeli procesów procesów typu zombie.
#include <signal.h>
#include <sys/wait.h>
void reap(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0)
; /* reap all finished children */
}Sygnały, których nie można przechwycić
Dwa sygnały są bezwzględne: SIGKILL zawsze kończy proces, a SIGSTOP zawsze go zatrzymuje. Nie można ich przechwycić, zablokować ani zignorować, co daje systemowi gwarantowany sposób kontrolowania procesów.
Szybki test
Sprawdź swoją wiedzę o sygnałach.
Podsumowanie
Dowiedział się Pan / Dowiedziała się Pani, jak używać sygnałów do asynchronicznego powiadamiania.
- Instaluj handlery za pomocą
sigaction, a nie starej funkcjisignal - Handlery muszą być bezpieczne asynchronicznie względem sygnałów; najlepiej ustawiać flagę
- Wysyłaj sygnały za pomocą
kill/raise, a blokuj je za pomocąsigprocmask - Zbieraj procesy potomne po SIGCHLD; sygnałów SIGKILL i SIGSTOP nie można przechwycić
Często zadawane pytania
Czy lekcja „Sygnały” jest bezpłatna?
Tak — pełny tekst „Sygnały” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C Academy, przejdź na CoddyKit PRO. Kurs C Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Sygnały”?
Asynchroniczne powiadomienia Ćwiczysz C Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C Academy?
Nie wymagamy żadnego doświadczenia. C Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Sygnały”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C Academy?
Tak. Każda lekcja C Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.