Linux 信号
信号的概念
最常见的信号就是在bash下启动一个程序按Ctrl+c 产生的硬件中断。如果CPU当前正在执行当前代码,则该进程的用户空间代码暂停,CPU就从用户态切换到内核态处理中断。
BTW
:Ctrl-c
产生的信号只能是前台进程发送,有些通过命令后+&
放到后台运行,这样不必等待进程结束就可以接受新的命令,shell就可以在一个前台进程的同时跑多个后台进程,信号相对于进程的控制流程来说是异步的。
系统定义的信号列表
luyunchengdeMacBook-Pro:~ luyuncheng$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE
9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG
17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGINFO 30) SIGUSR1 31) SIGUSR2
这些编号和宏定义以及介绍在usr/include/signal.h
可以找到。
./asm-generic/signal.h:10:#define SIGHUP 1
./x86_64-linux-gnu/bits/signum.h:33:#define SIGHUP 1 /* Hangup (POSIX). */
./x86_64-linux-gnu/asm/signal.h:19:#define SIGHUP 1
在编号34以上为实时信号,34以下为非实时信号。
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 read |
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 | ~~ | 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 |
其中Action中,Term表示终止当前进程,Core表示终止当前进程并且CoreDump,Ign表示忽略信号,Stop表示停止当前进程,Cont表示继续执行先前停止的进程。
产生信号的条件有:
- bash按下时,终端会发送信号给前台,
Ctrl-C
产生SIGINT信号,Ctrl-\
产生SIGQUIT信号,Ctrl-Z
产生SIGTSTP信号,上述信号使得进程停止。 - 硬件异常信号,条件由硬件检测到并通知内核,然后内核向当前进程发送信号。例如执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
- 一个进程调用kill(2)函数可以发送信号给另一个进程。
- 可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。
- 当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号。
信号的产生
终端产生信号
前面说Term是使终止当前进程,Core表示终止当前进程并有CoreDump。CoreD