Unix系统中信号SIGKILL和SIGSTOP

 signal定义

unix类系统中,信号是进程间通讯的方式,linux系统中定义的Signal常量及其说明可以在/usr/include/bits/signum.h的头文件中,定义如下:

/* Signals.  */
#define SIGHUP          1       /* Hangup (POSIX).  */
#define SIGINT          2       /* Interrupt (ANSI).  */
#define SIGQUIT         3       /* Quit (POSIX).  */
#define SIGILL          4       /* Illegal instruction (ANSI).  */
#define SIGTRAP         5       /* Trace trap (POSIX).  */
#define SIGABRT         6       /* Abort (ANSI).  */
#define SIGIOT          6       /* IOT trap (4.2 BSD).  */
#define SIGBUS          7       /* BUS error (4.2 BSD).  */
#define SIGFPE          8       /* Floating-point exception (ANSI).  */
#define SIGKILL         9       /* Kill, unblockable (POSIX).  */
#define SIGUSR1         10      /* User-defined signal 1 (POSIX).  */
#define SIGSEGV         11      /* Segmentation violation (ANSI).  */
#define SIGUSR2         12      /* User-defined signal 2 (POSIX).  */
#define SIGPIPE         13      /* Broken pipe (POSIX).  */
#define SIGALRM         14      /* Alarm clock (POSIX).  */
#define SIGTERM         15      /* Termination (ANSI).  */
#define SIGSTKFLT       16      /* Stack fault.  */
#define SIGCLD          SIGCHLD /* Same as SIGCHLD (System V).  */
#define SIGCHLD         17      /* Child status has changed (POSIX).  */
#define SIGCONT         18      /* Continue (POSIX).  */
#define SIGSTOP         19      /* Stop, unblockable (POSIX).  */
#define SIGTSTP         20      /* Keyboard stop (POSIX).  */
#define SIGTTIN         21      /* Background read from tty (POSIX).  */
#define SIGTTOU         22      /* Background write to tty (POSIX).  */
#define SIGURG          23      /* Urgent condition on socket (4.2 BSD).  */
#define SIGXCPU         24      /* CPU limit exceeded (4.2 BSD).  */
#define SIGXFSZ         25      /* File size limit exceeded (4.2 BSD).  */
#define SIGVTALRM       26      /* Virtual alarm clock (4.2 BSD).  */
#define SIGPROF         27      /* Profiling alarm clock (4.2 BSD).  */
#define SIGWINCH        28      /* Window size change (4.3 BSD, Sun).  */
#define SIGPOLL         SIGIO   /* Pollable event occurred (System V).  */
#define SIGIO           29      /* I/O now possible (4.2 BSD).  */
#define SIGPWR          30      /* Power failure restart (System V).  */
#define SIGSYS          31      /* Bad system call.  */
#define SIGUNUSED       31

signal捕获

通过signal函数可以自定义对信号的处理方法,定义如下:

signal(int signum, void (signalHandler*)(int));  //自定义信号处理
signal(int signum, SIG_IGN); //忽略信号

示例

#include <iostream>
#include <signal.h>
#include <unistd.h>

/**
 * 处理signal信号
 **/
void signalHandler(int signal) {
    std::cout << "signalHandler get signlal " << signal << std::endl;
}

int main(int argc, char* argv[]) {

    /**
     * ctrl + c
     **/
    signal(SIGINT, signalHandler); 
    
    /**
     * ctrl + \
     **/
    signal(SIGQUIT, signalHandler);

    
    while(true) {
        sleep(1);
    }
}

在一个运行的程序的控制终端键入特定的组合键可以向它发送某些信号:
Ctrl-C发送INT信号(SIGINT);默认情况下,这会导致进程终止。
Ctrl-Z发送TSTP信号(SIGTSTP);默认情况下,这会导致进程挂起。
Ctrl-\发送QUIT信号(SIGQUIT);默认情况下,这会导致进程终止并且将内存中的信息转储到硬盘(核心转储)。
(这些组合键可以通过stty命令来修改。)

运行时输入:ctrl+c和ctrl+\

无法捕获的信号信号SIGKILL和SIGSTOP

所有的信号中,只有信号SIGKILL和SIGSTOP无法被捕捉到,当SIGSTOP被程序接收到时,默认会暂停执行,如果需要继续执行发送SIGCONT信号,当SIGKILL接收到时会直接关闭,不能执行任何清理,下面以一个每秒写入一次文件的程序做示例。

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>

/**
 * 处理signal信号
 **/
void signalHandler(int signal) {
    std::cout << "signalHandler get signlal " << signal << std::endl;
}

int main(int argc, char* argv[]) {

    /**
     * kill -9
     **/
    signal(SIGKILL, signalHandler); 
    
    /**
     * ctrl + z
     **/
    signal(SIGSTOP, signalHandler);

    
    int fd = open("/home/course/unix/output.data", O_RDWR | O_TRUNC | O_CREAT);
    if(fd == -1) {
        std::perror("/home/course/unix/output.data");
        exit(1);
    }
    while(true) {
        sleep(1);
        write(fd, "abc\n", 4);
    }
}

  执行程序后,tail查看output.data文件一直在追加写入

发送SIGSTOP

kill -SIGSTOP 12266

此时的文件读写暂停,程序暂停运行了,如果需要程序继续运行,发送SIGCONT信号,如下,又开始继续追加

发送SIGKILL杀掉进程

在以上两个SIGKILL和SIGSTOP信号发送过程中,进程都无法捕获到对应的信号。

 参考:

https://major.io/2009/06/15/two-great-signals-sigstop-and-sigcont/

https://serverfault.com/questions/319684/what-s-s1-t-r-mean-in-ps-ax-ps-list

what-is-the-difference-between-sigstop-and-sigtstp

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章