linux signal 函数

在看项目的代码,对父进程fork的子进程的各种死法,父进程会受到子进程什么样的信号产生了疑虑。

通过细看apue,可以整理出一下流程:

对于子进程(abort, ctrl+c, a/0, 被kill, *invalid_addr 等等)各种死法,子进程会收到对应的信号(如 SIGABRT, SIGKILL,SIGFPE ..等等信号),这些信号是按照 [硬件/软件] -> 内核 -> 进程  顺序发送给子进程的。

这只是子进程接收信号的表述,实际上子进程本身也可能是导致发送信号的原因,比如子进程运行结束,会导致内核向父进程发送 SIGCHLD 信号。

因此不管子进程是正常死的(return 0)还是异常死的(kill),也不管异常死的方式。只要子进程运行结束了,内核都会负责向父进程报丧(发 SIGCHLD 信号)。而如果父进程不用wait或者waitpid接收报丧,那么子进程将会变成僵尸进程(没人收尸)。

如果父进程在子进程之前运行终止,那么内核会在一个进程终止时,逐个检查所有活动进程,以判断它是否是正要终止的进
程的子进程,如果是(此时子进程成为孤儿进程),则该进程的父进程 I D就更改为1 ( i n i t进程的I D ),由init进程收养。以确保系统每个子进程都有一个父进程。因为init进程会调用wait取得子进程的消亡状态,因此孤儿进程不会变成僵尸进程。

 

有了上面的理解,下面的代码就好看懂了:

sig_hander(int signo)

{

        int save_errno = errno;

        //switch(signo)

        //case SIGCHLD, SIGINT, SIGTERM

        //do something

        errno = save_errno;

}

父进程:

signal(SIGCHLD, sig_hander);  //处理子进程终止产生的信号,此时sig_hander 的参数是 SIGCHLD

signal(SIGINT, sig_hander);   //处理中断信号 ctrl + c,此时sig_hander 的参数是 SIGINT

signal(SIGTERM, sig_hander);  //处理终止信号,此时sig_hander 的参数是 SIGTERM

//注意不能捕获,SIGKILL 和 SIGSTOP 这两个信号。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章