Prayer

在一般中寻求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

我对信号的理解

Posted on 2009-01-13 11:07 Prayer 阅读(327) 评论(0)  编辑 收藏 引用 所属分类: LINUX/UNIX/AIX

自己写了一些代码,看看到底内部如何处理的。
#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,则进程不会退出,只是回到原来被中断的地方继续执行。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理