09_signal()函数的使用

/*
    signal()信号捕捉函数忽略以及对pause造成的影响

    pause()使调用进程挂起直至捕捉到一个信号;
         只有执行了一个信号处理程序并从其返回时,pause()才返回。
             这种情况下,pause 返回-1 ,errno 置为EINTR

信号函数的原型:
 void (*  signal(int signum, void (*fun)(int) )  )(int);

 定义宏定义修改,可以简化如下
    typedef void (*sighandler_t)(int);
       sighandler_t signal(int signum, sighandler_t handler);

    #define SIG_ERR (void (*)())-1
    #define SIG_DFL (void (*)())0
    #define SIG_IGN (void (*)())1
*/
/*
    signal()处理僵尸进程
*/
#if 0
void test()
{
    pid_t pid;

    //捕捉SIGCHLD,对此信号的处理是忽略
    #if 1
    signal(SIGCHLD, SIG_IGN);   //父进程忽略子进程的退出,可以收尸
    #endif
    //signal(SIGKILL, SIG_IGN); //err SIGKILL 和SIGSTOP不能忽略
    pid = fork();
    if (pid == -1)
    {
        perror("fork err");
        exit(0);
    }

    if (pid == 0)
    {
        printf("child.....\n");
        exit(0);//子进程运行完就退出了
    }

    while(1)
    {
        printf("子进程 pid = %d\n", pid);
        pause();
    }
}
/*
    运行结果
        屏蔽signal(SIGCHLD, SIG_IGN)
        会出现僵尸进程
        2233  2234  2233  1613 pts/8     2233 Z+    1000   0:00 [dm02_signale] <defunct>
    打开注释
     1613  2294  2294  1613 pts/8     2294 S+    1000   0:00 ./dm02_signale
     2144  2296  2296  2144 pts/9     2296 R+    1000   0:00 ps -ajx
    没有产生僵尸进程
*/
#endif
/*
    信号的安装与恢复(恢复信号处理的默认状态)
*/
#if 1
void handler(int num)
{
    printf("recv num:%d \n", num);  
    if (num == SIGQUIT)
    {
        exit(0);
    }
}

void test()
{
    char tmpchar;
    signal(SIGINT, handler);
    printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
    while( (tmpchar = getchar()) != 'a' )
    {
        pause();//让进程进入可中断睡眠
    }

    printf("恢复信号默认行为\n");
    //让这个信号恢复默认行为 SIG_DFL
    signal(SIGINT, SIG_DFL);
    while(1)
    {
        pause();
    }
    printf("main...end\n"); 
}
#endif
/*

signal 的返回值
RETURN VALUE
       signal()  returns the previous value of the signal handler, or SIG_ERR on error.
       In the event of an error, errno is set to indicate the cause
*/
#if 0
void handler(int num)
{
    printf("recv num:%d \n", num);  
    if (num == SIGQUIT)
    {
        exit(0);
    }
}

//测试函数返回值 返回的是信号以前的行为
void test()
{
    char tmpchar;
    //注册一个信号
    //SIGINT  是ctrl+c 会产生2号信号。。。 中断应用程序
    //sighandler_t signal(int signum, sighandler_t handler);
  __sighandler_t old = signal(SIGINT, handler);
    if (SIG_ERR == old)
    {
        perror("signal err"); //errno   
    }

    printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
    while( (tmpchar = getchar()) != 'a' )
    {
        pause();
    }
    //让这个信号恢复默认行为 SIG_DFL
    signal(SIGINT, old);
    while(1)
    {
        pause();
    }
    printf("main...end\n")
}

#endif
#if  0
void handler(int num)
{
    printf("recv num:%d \n", num);  
    if (num == SIGQUIT)
    {
        exit(0);
    }
}
//signal的正规写法
void test()
{
    //注册一个信号
    //SIGINT  是ctrl+c 会产生2号信号。。。 中断应用程序
    if (signal(SIGINT, handler) == SIG_ERR)
    {
            perror("signal err"); //errno
            exit(0);
    } 
    while(1)
    {
        pause();
    }
    printf("main...end\n");
}
#endif

int main()
{
     test();
     return 0;  
}

猜你喜欢

转载自blog.csdn.net/WUZHU2017/article/details/81875882
今日推荐