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无法被捕捉到。
当SIGKILL被发送给一个程序时,它使程序立即终止,这个信号不能被捕获或忽略,同时接收这个信号的进程在收到这个信号时不能执行任何清理。
僵尸进程不能被杀死,因为它们已经死亡,只等待它们的父进程回收它们。
处于阻塞状态的进程不会死亡,直到它们再次醒来。
init进程是特殊的:它不获得它不想处理的信号,因此它可以忽略SIGKILL。
因为SIGKILL不给进程任何在终止时做清理操作的机会,在大部分系统关闭过程中,在采取SIGKILL之前,使用信号SIGTERM使进程终止的尝试先被作出。
为了加速计算机关闭过程,Mac OS X 10.6,也称为雪豹,会将SIGKILL发送给已经标记它们自己为“干净”的应用程序,以加快关机速度,同时,很可能地,没有坏作用。[2]
即使SIGKILL被发送给它,一个正在不可中断睡眠的进程也可能不会终止(并且释放它的资源)。这是少数几个一个UNIX系统可能需要被重新启动来解决临时软件问题的例子中的一个。
示例:
#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[]) { /** * kill -9 **/ signal(SIGKILL, signalHandler); /** * ctrl + z **/ signal(SIGSTOP, signalHandler); while(true) { sleep(1); } }
ctrl+z(其实此处的程序收到的时SIGSTP,详见:what-is-the-difference-between-sigstop-and-sigtstp),执行后程序还在继续运行。
kill -9
发送SIGSTOP和SIGCONT
注意查看MyUnix的状态从S(休眠)转到T(停止),状态参考
D 不可中断 Uninterruptible sleep (usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核2.6开始无效)
X 死掉的进程
< 高优先级
N 低优先级
L 有些页被锁进内存
s 包含子进程
+ 位于后台的进程组;
l 多线程,克隆线程 multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
参考:
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