转自 https://www.cnblogs.com/gaorong/p/6430905.htmlhtml
在linux下有不少信号,按可靠性分为可靠信号和非可靠信号,按时间分为实时信号和非实时信号,linux进程也有三种方式来处理收到的信号:linux
(1)忽略信号,即对信号不作任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP;shell
(2)捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数;apache
(3)执行缺省操做,Linux对每种信号都规定了默认操做。编程
Linux进程对实时信号的缺省反应是进程终止。可是对于高性能服务器编程来讲,这是致命的缺陷,对于这类服务器须要保证在收到各类信号后仍然能够可靠运行,因此咱们须要在理解各类信号的原因和正确的处理方式。本文将笔者常常碰到的一些信号进行整理,结合本身的使用经验简要分析。服务器
SIGHUP和控制台操做有关,当控制台被关闭时系统会向拥有控制台sessionID的全部进程发送HUP信号,默认HUP信号的action是 exit,若是远程登录启动某个服务进程并在程序运行时关闭链接的话会致使服务进程退出,因此通常服务进程都会用nohup工具启动(该命令就是让忽略该信号)或写成一个 daemon(利用setsid进行)。网络
如下五组能够放在一块类比session
SIGINT 终止进程,一般咱们的Ctrl+C就发送的这个消息。app
SIGQUIT 和SIGINT相似, 但由QUIT字符(一般是Ctrl- \ )来控制. 进程收到该消息退出时会产生core文件。tcp
SIGKILL 消息编号为9,咱们常常用kill -9来杀死进程发送的就是这个消息,程序收到这个消息当即终止,这个消息不能被捕获,封锁或这忽略,因此是杀死进程的终极武器。
SIGTERM 是不带参数时kill默认发送的信号,默认是杀死进程。
1.SIGINT SIGTERM区别
前者与字符ctrl+c关联,后者没有任何控制字符关联。
前者只能结束前台进程,后者则不是。
2.SIGTERM SIGKILL的区别
前者能够被阻塞、处理和忽略,可是后者不能够。
KILL命令的默认不带参数发送的信号就是SIGTERM.让程序有好的退出。
SIGTERM比较友好,进程能捕捉这个信号,根据您的须要来关闭程序。在某些状况下,假如进程正在进行做业并且不能中断,那么进程能够忽略这个SIGTERM信号。
由于SIGTERM能够被阻塞,因此有的进程不能被结束时,须要用kill发送SIGKILL。即:kill-9 进程号。
SIGSTOP 中止进程的执行,同SIGKILL同样不能够被应用程序所处理,注意它和terminate以及interrupt的区别:该进程还未结束, 只是暂停执行.由 Ctrl+Z 控制,用户可使用使用fg/bg操做恢复执行前台或后台的进程。fg命令在前台恢复执行被挂起的进程,此时可使用ctrl-z再次挂起该进程,bg命令在后台恢复执行被挂起的进程,而此时将没法使用ctrl-z再次挂起该进程。
SIGCONT 当SIGSTOP发送到一个进程时,一般的行为是暂停该进程的当前状态。若是发送SIGCONT信号,该进程将仅恢复执行。除了其余目的,SIGSTOP和SIGCONT用于Unix shell中的做业控制,没法捕获或忽略SIGCONT信号。
SIGPIPE 这个是向一个没有读进程的管道写数据产生的错误,这种解释过于官方。在网络编程中这个信号发生在若是客户端已经关闭了套接字, 而服务器调用了一次write,服务器就会收到一个RST segment,若是服务器再次调用write,这个时候就会产生SIGPIPE信号,系统默认的处理方式是关掉这个进程, 可是对于一个高可用的服务器程序来讲,须要手动处理这个信号,因此你会看到许多服务器程序代码会在前面显式加上signal (SIGPIPE, SIG_IGN)来忽略这个信号。
SIGCHILD 这个一样是高性能服务器须要关注的信号,若是服务器采用fork产生的子进程推出后要调用wait进行资源回收,防止僵尸进程的产生,可是若是程序对子进程退出后的状态不感兴趣的话能够调用signal(SIGCHLD,SIG_IGN); 交给系统init去回收。子进程也不会产生僵尸进程了。
SIGSEGV 就是SegmentFault 试图访问未分配给本身的内存, 或试图往没有写权限的内存地址写数据,官方举得三个例子是:
- buffer overflow --- usually caused by a pointer reference out of range. 野指针
- stack overflow --- please keep in mind that the default stack size is 8192K. 栈溢出
- illegal file access --- file operations are forbidden on our judge system. 非法文件访问
SIGBUS 指针所对应的地址是有效地址,但总线不能正常使用该指针。一般是未对齐的数据访问所致。试图访问一块无文件内容对应的内存区域,好比超过文件尾的内存区域,或者之前有文件内容对应,如今为另外一进程截断过的内存区域。apache爆出的一个bug就是mmap调用的时候文件发生改变就会爆出这个错误,具体参考这篇精彩的博客是 : 由mmap引起的SIGBUS
关于上面两个信号,《UNP》卷二中对于共享内存mmap引起这两个错误的缘由用一张图描述:
SIGBUS意味着咱们是在内存映射区内访问,可是已超出了底层支撑对象的大小。SIGSEGV则意味着我i们在内存映射区之外访问。
SIGURG I/O紧急信号,也就是tcp传输带外数据时使用,可是tcp手册 RFC6093中已经不建议使用紧急指针了,因此这个信号也就没什么用了。
SIGIO 当描述符上能够进行I/O时产生这个信号,这时五大IO模型中信号驱动IO模型的实现信号。
SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间.alarm函数使用该信号.
以上就是编程中常见到的信号,也是最引人关注的信号,至于其余信号,之后想起再写吧。
2018.6.14 append:
https://www.linuxjournal.com/article/10815 shell 捕获信号