自己写了一些代码,看看到底内部如何处理的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <stdarg.h>
pid_t pid;
void mydebug(char *fmt, ...){
va_list argptr;
FILE *pFile;
if( ( pFile = fopen( "./mylog", "a+" ) ) == NULL )
return;
va_start( argptr, fmt );
vfprintf( pFile, fmt, argptr );
va_end( argptr );
fclose( pFile );
}
void sigTermHandler()
{
kill(pid,SIGTERM);
}
int main(){
int i=0;
signal(SIGTERM,(void (*)( ))sigTermHandler);
mydebug("创建进程\n");
if((pid=fork())<0){
mydebug("fork失败\n");
return -1;
}
if(pid==0){
if(execl("./sig2",(char *) 0) < 0){
mydebug("execl失败\n");
exit(1);
}
}
mydebug("等待100秒\n");
sleep(10);
while(1){
kill(pid,SIGUSR1);
mydebug("已发送了USR1信号 %d\n",i++);
sleep(5);
}
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <stdarg.h>
void mydebug(char *fmt, ...){
va_list argptr;
FILE *pFile;
if( ( pFile = fopen( "./mylog", "a+" ) ) == NULL )
return;
va_start( argptr, fmt );
vfprintf( pFile, fmt, argptr );
va_end( argptr );
fclose( pFile );
}
void sigUsr1Handler()
{
signal(SIGUSR1,SIG_IGN);
mydebug("进入了信号处理函数\n");
signal(SIGUSR1,(void (*)( ))sigUsr1Handler);
}
void sigTermHandler()
{
mydebug("接受到SIGTERM信号,退出\n");
exit(0);
}
int main(){
int i=0;
signal(SIGUSR1,(void (*)( ))sigUsr1Handler);
signal(SIGTERM,(void (*)( ))sigTermHandler);
mydebug("进入循环\n");
while(1){
sleep(10);
mydebug("i=%d\n",i++);
}
mydebug("退出程序\n");
return 0;
}
cc sig1.c -o sig1
cc sig2.c -o sig2
(使用-o sig1.o没有编译出应用程序,也没有提示错误)
sig1&
tail -f mylog
创建进程
等待100秒
进入循环
已发送了USR1信号 0
进入了信号处理函数
i=0
已发送了USR1信号 1
进入了信号处理函数
i=1
已发送了USR1信号 2
进入了信号处理函数
i=2
已发送了USR1信号 3
进入了信号处理函数
i=3
已发送了USR1信号 4
进入了信号处理函数
i=4
已发送了USR1信号 5
进入了信号处理函数
i=5
已发送了USR1信号 6
进入了信号处理函数
i=6
已发送了USR1信号 7
进入了信号处理函数
i=7
已发送了USR1信号 8
进入了信号处理函数
i=8
已发送了USR1信号 9
进入了信号处理函数
此时,在shell下使用kill杀死sig1,则根据sig1的sigTermHandler,sig2会被杀死。
接受到SIGTERM信号,退出
已发送了USR1信号 10
已发送了USR1信号 11
已发送了USR1信号 12
已发送了USR1信号 13
已发送了USR1信号 14
已发送了USR1信号 15
已发送了USR1信号 16
已发送了USR1信号 17
但是sig1本身没有被杀死,这时因为没有在sigTermHandler里面重新注册signal(SIGTERM,(void (*)( ))sigTermHandler);
执行了一次sigTermHandler后,对SIGTERM的处理恢复到系统默认的处理。
然后再一次执行kill,杀死sig1,则sig1被杀死。
--可以看出,如果信号处理函数内部没有exit,则进程不会退出,只是回到原来被中断的地方继续执行。