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