自己寫了一些代碼,看看到底內部如何處理的。
#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,則進程不會退出,只是回到原來被中斷的地方繼續執行。