看《Unix环境高级编程》第十章关于信号的内容,一个例子程序10-3.c
#include<apue.h>
#include<sys/wait.h>
static void sig_cld(int);
int main()
{
pid_t pid;
if(signal(SIGCLD,sig_cld)==SIG_ERR)
perror("signal error");
if((pid = fork()) < 0)
{
perror("fork error");
}else if(pid == 0)
{ /*child*/
sleep(2);
_exit(0);
}
pause(); /*parent*/
exit(0);
}
static void sig_cld(int signo) /*interrupts pause()*/
{
pid_t pid;
int status;
printf("SIGCLD received\n");
if(signal(SIGCLD,sig_cld)==SIG_ERR) /* reestablish handler */
perror("signal error");
if((pid = wait(&status)) < 0) /* fetch child status */
perror("wait error");
printf("pid = %d \n",pid);
}
在信号处理函数中,又重建了这个信号处理函数。我的理解是,既然重建了,会不会一直重建下去啊?就如嵌套函数一样,如果没有返回条件,那么就一直嵌套下去了。但是我运行之后直接就返回了,好像都没重建一样,而且我注释掉重建的那2行代码,重新运行,运行结果是一样的。
在网上查资料,有人说先wait再重建,这重建是干啥用的啊
man pause
DESCRIPTION
pause() causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching
function.
RETURN VALUE
pause() only returns when a signal was caught and the signal-catching function returned. In this case pause() returns -1, and errno is set to EINTR.
所以你的sig_cld不返回,则pause函数也不返回,循环接收信号,wait返回时表示子进程结束,或出错
因此程序的结果是子进程结束前是无法通过输入信号打断父进程暂停并退出
这程序fork一个子进程,父进程pause,2秒后子进程就退出了,产生一个SIGCLD信号,捕捉到这个信号之后,就处理这个信号,问题是信号处理函数中,又来一个signal(SIGCLD,sig_cld),好像是叫什么重建函数(reestablish handler),我理解的这个就跟递归一样,不停地递归下去。但事实上,程序先printf("SIGCLD received\n"),2秒后打印子进程ID就退出了。我的问题是这个reestablish handler有什么作用?注释掉这个运行结果也是一样的
我就是看《Unix环境高级编程》第三版,这个程序就是书上的例子。你的意思是说即使写了这个信号处理函数,系统还是会给默认处理掉,为了避免默认处理掉,所以在信号处理函数中再给它捕捉一次。如果在信号处理函数中,restablish handler代码前又来了个SIGCLD信号,那么程序又默认处理了,也就是退出,后面的代码都不会执行。
那我的理解有问题,signal(SIGCLD,sig_cld)的sig_cld函数里面又调用signal(SIGCLD,sig_cld)不会一直调用下去,是要有信号才触发。我再去看看
差不多了解了,刚开始学Unix,对新旧版本这些都没什么概念,这本《Unix环境高级编程》也就看了第十章的前几个小结,又找了些资料,总算明白了你说的意思,