C编程-处理SIGTERM消息

2018-06-15  本文已影响34人  louyang

Linux系统中,kill命令用于给后台程序发消息,SIGTERM是众多消息中之一,也是缺省的消息。

$ kill 2573  // send SIGTERM to the process which pid is 2573

$ kill -l    // show all SIGNAL
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

C代码,接受并处理SIGTERM消息。

#include <stdio.h>  // printf(), perror()
#include <stdlib.h> // exit()
#include <signal.h> // sig*()
#include <unistd.h> // getpid()
#include <string.h> // memset()

void handle_signal(int signal);

int main()
{
    struct sigaction sa;

    printf("My pid is: %d\n", getpid());

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &handle_signal;

    if (sigaction(SIGTERM, &sa, NULL) == -1) {
        perror("Error: cannot handle SIGINT"); // Should not happen
    }

    // Will always fail, SIGKILL is intended to force kill your process
    if (sigaction(SIGKILL, &sa, NULL) == -1) {
        perror("Cannot handle SIGKILL"); // Will always happen
        printf("You can never handle SIGKILL anyway...\n");
    }

    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("Error: cannot handle SIGINT"); // Should not happen
    }

    for (;;) {
        printf("\nSleeping for ~3 seconds\n");
        sleep(3);
    }
}

void handle_signal(int signal)
{
    switch (signal) {
        case SIGTERM:
            printf("Caught SIGTERM, exiting now\n");
            exit(0);
        case SIGINT:
            printf("Caught SIGINT, exiting now\n");
            exit(0);
        case SIGKILL:
            printf("Caught SIGKILL, exiting now\n");
            exit(0);
        default:
            fprintf(stderr, "Caught wrong signal: %d\n", signal);
            return;
    }

    printf("Done handling %s\n\n", signal);
}

编译运行:

$ gcc a.c && ./a.out
My pid is: 10703
Cannot handle SIGKILL: Invalid argument
You can never handle SIGKILL anyway...

Sleeping for ~3 seconds

Sleeping for ~3 seconds

打开另外一个终端窗口,输入:

$ kill 10703

第一个窗口中,可以看到:

Caught SIGTERM, exiting now
参考

https://major.io/2010/03/18/sigterm-vs-sigkill/
https://gist.github.com/aspyct/3462238
https://airtower.wordpress.com/2010/06/16/catch-sigterm-exit-gracefully/
https://www.cyberciti.biz/faq/unix-kill-command-examples/

上一篇 下一篇

猜你喜欢

热点阅读