0Pricing
C Academy · Lekcja

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ą:

  • SIGINT przerwanie (Ctrl-C)
  • SIGTERM uprzejma prośba o zakończenie procesu
  • SIGKILL wymuszone zakończenie (nie można go przechwycić)
  • SIGCHLD proces potomny zmienił stan
  • SIGSEGV nieprawidł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 funkcji signal
  • 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.

Wszystkie lekcje w tym kursie

  1. Potoki
  2. Pamięć współdzielona
  3. Kolejki komunikatów
  4. Sygnały
← Powrót do C Academy