APUE.05a::信号

Linux 支持的全部信号

kill -l 可以查看所有支持的信号和其对应值:
../_images/21.Operating-System-List-all-Signal.png

Linux 共有 64 种信号,前 32 种为不可靠信号,后 32 种为可靠信号。

信号 类型 说明
SIGHUP 1 Term 终端控制进程结束(终端连接断开)
SIGINT 2 Term 用户发送 INTR 字符(Ctrl+C)触发
SIGQUIT 3 Core 用户发送 QUIT 字符(Ctrl+/)触发
SIGILL 4 Core 非法指令(程序错误、试图执行数据段、栈溢出等)
SIGABRT 6 Core 调用 abort 函数触发
SIGFPE 8 Core 算术运行错误(浮点运算错误、除数为零等)
SIGKILL 9 Term 无条件结束程序(不能被捕获、阻塞或忽略)
SIGSEGV 11 Core 无效内存引用(试图访问不属于自己的内存空间、对只读内存空间进行写操作)
SIGPIPE 13 Term 消息管道损坏(FIFO/Socket 通信时,管道未打开而进行写操作)
SIGALRM 14 Term 时钟定时信号
SIGTERM 15 Term 结束程序(可以被捕获、阻塞或忽略)
SIGUSR1 30,10,16 Term 用户保留
SIGUSR2 31,12,17 Term 用户保留
SIGCHLD 20,17,18 Ign 子进程结束(由父进程接收)
SIGCONT 19,18,25 Cont 继续执行已经停止的进程(不能被阻塞)
SIGSTOP 17,19,23 Stop 停止进程(不能被捕获、阻塞或忽略)
SIGTSTP 18,20,24 Stop 停止进程(可以被捕获、阻塞或忽略)
SIGTTIN 21,21,26 Stop 后台程序从终端中读取数据时触发
SIGTTOU 22,22,27 Stop 后台程序向终端中写数据时触发
SIGTRAP 5 Core Trap 指令触发(如断点,在调试器中使用)
SIGBUS 0,7,10 Core 非法地址(内存地址对齐错误)
SIGPOLL Term Pollable event (Sys V). Synonym for SIGIO
SIGPROF 27,27,29 Term 性能时钟信号(包含系统调用时间和进程占用 CPU 的时间)
SIGSYS 12,31,12 Core 无效的系统调用(SVr4)
SIGURG 16,23,21 Ign 有紧急数据到达 Socket(4.2BSD)
SIGVTALRM 26,26,28 Term 虚拟时钟信号(进程占用 CPU 的时间)(4.2BSD)
SIGXCPU 24,24,30 Core 超过 CPU 时间资源限制(4.2BSD)
SIGXFSZ 25,25,31 Core 超过文件大小资源限制(4.2BSD)

信号的分类:

Type Desc
Term Default action is to terminate the process.
Ign Default action is to ignore the signal.
Core Default action is to terminate the process and dump core (see core(5)).
Stop Default action is to stop the process.
Cont Default action is to continue the process if it is currently stopped.

产生信号的几种方式

  • 用户按键产生信号, 运行在 shell 终端的进程,通过键盘输入某些组合键给进程发送信号:
    • Ctrl-C : SIGINT, 中断(Interrupt), 只能向前台进程发送, 可忽略
    • Ctrl-\ : SIGQUIT, 退出(Quit), 可忽略
    • Ctrl-Z : SIGSTP, 停止(Stop), 挂起的进程可以 fg 恢复
  • 硬件产生信号
    • 除 0: SIGFPE, CPU 运算单元产生异常并发送给进程,
    • 内存非法访问: SIGSEGV, 内存控制单元 MMU 产生
  • 通过 kill() 函数产生信号
    • kill : SIGTERM, 可被忽略
    • kill -2 : SIGINT, 同 Ctrl-C
    • kill -9 : SIGKILL, 不可忽略, 但导致进程无法完成清理?
    • kill -17 : SIGCHLD, 子进程死掉, 系统会向父进程发生 SIGCHLD 信号, 父进程可以选择是否处理
    • SIGCHLD: 子进程死掉, 系统会向父进程发生 SIGCHLD 信号, 父进程可以选择是否处理
    • SIGHUP: 在终端启动一个回话(session), 在这个终端里再启动的命令, 都是这个回话的子进程, 如果回话进程关闭, SIGHUP 会被发送到所有子进程

➤ 区分 Ctrl+z 和 Ctrl+c 的不同:

  • Ctrl+z 产生 SIGTSTP (挂起进程),但还未结束. 进程收到 SIGTSTP 后, 用 bg 1 可以让被挂起的程序在后台继续执行, 命令中的”1”是 job(作业号); 命令 fg 1 重新让进程切换到前台运行. 命令 jobs 查看在后台运行的任务.
  • Ctrl+c 产生 SIGINT (中断进程) 信号

一些常用信号

➤ kill 和 kill -9的区别:

  • kill -9是发送SIGKILL信号给进程,不支持被捕获和忽略,会导致进程直接退出。
  • kill 等价于 kill -15, 是发送 SIGTERM 信号给进程,可以被捕获和忽略,可以实现让进程优雅退出。

➤ SIGHUP 信号

SIGHUP信号在用户终端连接(正常或非正常)结束时发出。SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出。

  • 终端关闭时,操作系统会向与其关联的进程组发送 SIGHUP 信号。
  • session首进程退出时(如远程ssh登录),该信号会发送给与会话关联的各个进程。
  • 如果父进程退出导致子进程称为孤儿进程,且该进程组中有进程处于停止状态。该信号会被发送到该进程组中的每一个进程。

对于 SIGHUP 信号,使用 nohup xxx & 可以让终端退出后不发送 SIGHUP 信号,使其成为常驻进程。