信号分类与详解 (2) 终止进程类信号

1. 软硬件异常类信号(多数的该类信号得默认处理是core-dump)

2. 终止进程类信号

     1) SIGHUP 

       ‘SIGHUP’是一个信号,它按照惯例意味着“终端线路被挂断”

               SIGHUP信号与控制

UNIX中进程组织结构为 session (会话)包含一个前台进程组及一个或多个后台进程组,一个进程组包含多个进程。一个session可能会有一个session首进程,而一个session首进程可能会有一个控制终端。一个进程组可能会有一个进程组首进程。进程组首进程的进程ID与该进程组ID相等。这儿是可能会有,在一定情况之下是没有的。与终端交互的进程是前台进程,否则便是后台进程。

 

 SIGHUP会在以下3种情况下被发送给相应的进程:

  1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)

  2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程

  3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

 

系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出。

 

下面观察几种因终端关闭导致进程退出的情况,在这儿进程退出是因为收到了SIGHUP信号。login shell是session首进程。

 

首先写一个测试程序,代码如下:

#include <stdio.h>
#include <signal.h>
char **args;
void exithandle(int sig) {
	printf("%s : sighup received\n", args[1]);
}
int main(int argc, char **argv) {
	args = argv;
	signal(SIGHUP, exithandle);
	pause();
	return 0;
}





程序中捕捉SIGHUP信号后打印一条信息,pause()使程序暂停。

编译后的执行文件为sigtest。

 

1、命 令:sigtest front > tt.txt

   

操 作:关闭终端

   

结 果:tt.txt文件的内容为front : sighup received

   

原 因: sigtest是前台进程,终端关闭后,根据上面提到的第1种情况,login shell作为session首进程,会收到SIGHUP信号然后退出。根据第2种情况,sigtest作为前台进程,会收到login shell发出的SIGHUP信号。

 

2、命 令:sigtest back > tt.txt &

      

操 作:关闭终端

      

结 果:tt.txt文件的内容为 back : sighup received

      

原 因: sigtest是提交的job,根据上面提到的第1种情况,sigtest会收到SIGHUP信号。

 

3、命 令:写一个shell,内容为[sigtest &],然后执行该shell

      

操 作:关闭终端

      

结 果:ps -ef | grep sigtest 会看到该进程还在,tt文件为空

      

原 因: 执行该shell时,sigtest作为job提交,然后该shell退出,致使sigtest变成了孤儿进程,不再是当前session的job了,因此sigtest即不是session首进程也不是job,不会收到SIGHUP。同时孤儿进程属于后台进程,因此login shell退出后不会发送SIGHUP给sigtest,因为它只将该信号发送给前台进程。第3条说过若进程组变成孤儿进程组的时候,若有进程处于停止状态,也会收到SIGHUP信号,但sigtest没有处于停止状态,所以不会收到SIGHUP信号。

 

4、命 令:nohup sigtest > tt

      

操 作:关闭终端

      结 果:tt文件为空

      原 因: nohup可以防止进程收到SIGHUP信号

 

至此,我们就清楚了何种情况下终端关闭后进程会退出,何种情况下不会退出。


要想终端关闭后进程不退出有以下几种方法,均为通过shell的方式:

 1、编写shell,内容如下

       trap "" SIGHUP #
该句的作用是屏蔽SIGHUP信号,trap可以屏蔽很多信号

       sigtest

 2、nohup sigtest 可以直接在命令行执行,

       若想做完该操作后继续别的操作,可以 nohup sigtest &

 3、编写shell,内容如下

       sigtest &

       

其实任何将进程变为孤儿进程的方式都可以,包括fork后父进程马上退出。


2) SIGINT 

       程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。

3) SIGQUIT 

       和SIGINT类似, 但由QUIT字符(通常是Ctrl-\)来控制,用于通知前台进程组终止进程

            进程在因收到SIGQUIT退出时会产生core文件(core-dump), 在这个意义上类似于一个程序错误信号。

4) SIGKILL

       用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。(使用命令 kill -9 pid)

5) SIGTERM 

     程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,

         shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

3. 挂起进程类信号

4. 定时器信号

5.其他信号

你可能感兴趣的:(信号分类与详解 (2) 终止进程类信号)