GNU/Linux >> Znalost Linux >  >> Linux

Jak souvisí SIGINT s ostatními ukončovacími signály, jako jsou SIGTERM, SIGQUIT a SIGKILL?

SIGTERM a SIGKILL jsou určeny pro obecné účely požadavků "ukončit tento proces". SIGTERM (ve výchozím nastavení) a SIGKILL (vždy) způsobí ukončení procesu. SIGTERM může být chycen procesem (např. aby mohl provést vlastní vyčištění, pokud bude chtít), nebo dokonce zcela ignorován; ale SIGKILL nelze chytit ani ignorovat.

SIGINT a SIGQUIT jsou určeny speciálně pro požadavky z terminálu:pro generování těchto signálů lze přiřadit konkrétní vstupní znaky (v závislosti na nastavení ovládání terminálu). Výchozí akce pro SIGINT je stejný druh ukončení procesu jako výchozí akce pro SIGTERM a neměnná akce pro SIGKILL; výchozí akcí pro SIGQUIT je také ukončení procesu, ale mohou nastat další akce definované implementací, jako je generování výpisu jádra. V případě potřeby může být proces zachycen nebo ignorován.

SIGHUP, jak říkáte, má indikovat ztrátu terminálového spojení, spíše než být ukončovacím signálem jako takovým. Ale opět, výchozí akcí pro SIGHUP (pokud jej proces nezachytí nebo ignoruje) je ukončit proces stejným způsobem jako SIGTERM atd.

V definicích POSIX pro signal.h je tabulka který uvádí různé signály a jejich výchozí akce a účely, a kapitola Obecné rozhraní terminálu obsahuje mnohem více podrobností o signálech souvisejících s terminály.


Jak DarkDust poznamenal, mnoho signálů má stejné výsledky, ale procesy k nim mohou připojit různé akce tím, že rozlišují, jak je každý signál generován. Když se podívám na zdrojový kód jádra FreeBSD (kern_sig.c), vidím, že tyto dva signály jsou zpracovány stejným způsobem, ukončují proces a jsou doručeny do libovolného vlákna.

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */

man 7 signal

Toto je pohodlná nenormativní manuálová stránka projektu Linux man-pages, na kterou se často chcete podívat pro informace o signálu Linuxu.

Verze 3.22 zmiňuje zajímavé věci jako:

Signály SIGKILL a SIGSTOP nelze zachytit, zablokovat ani ignorovat.

a obsahuje tabulku:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process
SIGINT        2       Term    Interrupt from keyboard
SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal
SIGSEGV      11       Core    Invalid memory reference
SIGPIPE      13       Term    Broken pipe: write to pipe with no
                              readers
SIGALRM      14       Term    Timer signal from alarm(2)
SIGTERM      15       Term    Termination signal
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2
SIGCHLD   20,17,18    Ign     Child stopped or terminated
SIGCONT   19,18,25    Cont    Continue if stopped
SIGSTOP   17,19,23    Stop    Stop process
SIGTSTP   18,20,24    Stop    Stop typed at tty
SIGTTIN   21,21,26    Stop    tty input for background process
SIGTTOU   22,22,27    Stop    tty output for background process

který shrnuje signál Action která odlišuje např. SIGQUIT od SIGQUIT, protože SIGQUIT má akci Core a SIGINT Term .

Akce jsou zdokumentovány ve stejném dokumentu:

The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:

Term   Default action is to terminate the process.

Ign    Default action is to ignore the signal.
Core   Default action is to terminate the process and dump core (see core(5)).
Stop   Default action is to stop the process.
Cont   Default action is to continue the process if it is currently stopped.

Z hlediska jádra nevidím žádný rozdíl mezi SIGTERM a SIGINT, protože oba mají akci Term a oba se dají chytit. Zdá se, že jde pouze o „rozdíl běžného použití“:

  • SIGINT je to, co se stane, když z terminálu stisknete CTRL-C
  • SIGTERM je výchozí signál odesílaný kill

Některé signály jsou ANSI C a jiné ne

Podstatný rozdíl je v tom, že:

  • SIGINT a SIGTERM jsou ANSI C, takže jsou přenosnější
  • SIGQUIT a SIGKILL nejsou

Jsou popsány v sekci "7.14 Zpracování signálů " návrhu C99 N1256:

  • SIGINT příjem interaktivního signálu pozornosti
  • SIGTERM žádost o ukončení odeslaná programu

díky čemuž je SIGINT dobrým kandidátem pro interaktivní Ctrl + C.

POSIX 7

POSIX 7 dokumentuje signály pomocí signal.h záhlaví:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html

Tato stránka také obsahuje následující tabulku zajímavostí, která zmiňuje některé z věcí, které jsme již viděli v man 7 signal :

Signal    Default Action   Description
SIGABRT   A                Process abort signal.
SIGALRM   T                Alarm clock.
SIGBUS    A                Access to an undefined portion of a memory object.
SIGCHLD   I                Child process terminated, stopped,
SIGCONT   C                Continue executing, if stopped.
SIGFPE    A                Erroneous arithmetic operation.
SIGHUP    T                Hangup.
SIGILL    A                Illegal instruction.
SIGINT    T                Terminal interrupt signal.
SIGKILL   T                Kill (cannot be caught or ignored).
SIGPIPE   T                Write on a pipe with no one to read it.
SIGQUIT   A                Terminal quit signal.
SIGSEGV   A                Invalid memory reference.
SIGSTOP   S                Stop executing (cannot be caught or ignored).
SIGTERM   T                Termination signal.
SIGTSTP   S                Terminal stop signal.
SIGTTIN   S                Background process attempting read.
SIGTTOU   S                Background process attempting write.
SIGUSR1   T                User-defined signal 1.
SIGUSR2   T                User-defined signal 2.
SIGTRAP   A                Trace/breakpoint trap.
SIGURG    I                High bandwidth data is available at a socket.
SIGXCPU   A                CPU time limit exceeded.
SIGXFSZ   A                File size limit exceeded.

Init BusyBox

Výchozí reboot BusyBoxu 1.29.2 příkaz odešle SIGTERM procesům, uspí na sekundu a poté odešle SIGKILL. Zdá se, že jde o běžnou konvenci napříč různými distribucemi.

Když vypnete systém BusyBox pomocí:

reboot

vyšle signál procesu init.

Potom obslužný program init signálu skončí voláním:

static void run_shutdown_and_kill_processes(void)
{
    /* Run everything to be run at "shutdown".  This is done _prior_
     * to killing everything, in case people wish to use scripts to
     * shut things down gracefully... */
    run_actions(SHUTDOWN);

    message(L_CONSOLE | L_LOG, "The system is going down NOW!");

    /* Send signals to every process _except_ pid 1 */
    kill(-1, SIGTERM);
    message(L_CONSOLE, "Sent SIG%s to all processes", "TERM");
    sync();
    sleep(1);

    kill(-1, SIGKILL);
    message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
    sync();
    /*sleep(1); - callers take care about making a pause */
}

který se vytiskne na terminál:

The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes

Zde je minimální konkrétní příklad.

Signály odeslané jádrem

  • SIGKILL:
    • OOM zabiják:Co je RSS a VSZ ve správě paměti v Linuxu

Linux
  1. Linux Signals – příklad programu C pro zachycení signálů (SIGINT, SIGKILL, SIGSTOP atd.)

  2. Jak systemd řeší smrt dítěte řízeného procesu?

  3. Jak si Linux zachovává kontrolu nad CPU na jednojádrovém stroji?

  1. Jak Sticky Bit funguje?

  2. Účel .bashrc a jak to funguje?

  3. Linux – Jak linuxové jádro zná hlavní a vedlejší čísla zařízení?

  1. Linux – Může Ctrl+c odeslat signál Sigint více procesům?

  2. Jak zjistit, který proces zabíjí mysqld pomocí SIGKILL nebo SIGTERM na Linuxu

  3. Jak interně funguje copy_from_user z jádra Linuxu?