为什么我的信号处理程序执

时间:2016-11-05 05:16:47

标签: c linux fork wait kill

我正在学习Linux中的进程间通信,使用kill()向睡眠子进程发送信号。这是我的程序:

 8 void func(void);
 9 int main(void){
 10         int i, j;
 11         pid_t status, retpid;
 12         signal(17,func);
 13         if( i = fork() ){
 14                 printf("Parent:signal 17 will be sent to child!\n");
 15                 kill(i, 17);
 16                 wait(0);
 17                 printf("child process terminated\n");
 18                 }
 19         else{   
 20                 sleep(10);
 21                 printf("Child: A signal from my parent is received!\n");
 22                 exit(0);
 23         }
 24 }
 25 void func(void) 
 26 {
 27         printf("the signal has been sent!\n");
 28 }

用gcc编译,程序产生了异常结果,其中func()执行了两次:

./test4.out
Parent:signal 17 will be sent to child!
the signal has been sent!
Child: A signal from my parent is received!
the signal has been sent!
child process terminated

我分析了结果,然后删除了以下两行:

 16                 wait(0);
 17                 printf("child process terminated\n");

结果变得正常,func()只调用一次。似乎罪魁祸首是wait()函数,但为什么它会调用信号处理程序?

2 个答案:

答案 0 :(得分:2)

您正在向子进程发送信号17,因此会按预期调用其处理程序。

信号17是SIGCHLD。当子进程终止时,SIGCHLD被发送到父进程。当孩子退出时,将调用父母的处理程序。此信号不是来自父母;它来自操作系统,通知父母孩子的死亡。

答案 1 :(得分:0)

纠正过帐代码中的(大多数)错误后。

结果如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

void func( int );

int main(void)
{
    pid_t i;
    //pid_t status;
    //pid_t retpid;
    signal(17,func);


    if( (i = fork()) )
    {
        printf( "the fork'd child pid:%d\n", i );
        printf("Parent:signal 17 will be sent to child!\n");
        kill(i, 17);
        wait(NULL);
        printf("child process terminated\n");
    }

    else
    {   
        sleep(10);
        printf("Child: pid:%d\n", getpid());
        exit(0);
    }
}

void func( int theSignal) 
{
    if( 17 == theSignal )
    {
        fprintf( stdout, "the 17 signal has been processed by %d!\n", getpid());
    }

    else
    {
        fprintf( stdout, "the %d signal is processed\n", theSignal );
    }
}

,输出为:

the fork'd child pid:4845
Parent:signal 17 will be sent to child!
the 17 signal has been processed by 4845!
Child: pid:4845
the 17 signal has been processed by 4844!
child process terminated

这清楚地表明父母和孩子都处理信号

编辑:

但是,当使用如下代码中的唯一SIGUSR2值时:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

void func( int );

#define MY_SIGNAL (31)

int main(void)
{
    pid_t i;
    //pid_t status;
    //pid_t retpid;
    signal(17,func);
    signal(31,func);

    if( (i = fork()) )
    {
        printf( "the fork'd child pid:%d\n", i );
        printf("Parent:signal %d will be sent to child!\n", MY_SIGNAL);
        kill(i, MY_SIGNAL);
        wait(NULL);
        printf("child process terminated\n");
    }

    else
    {   
        sleep(10);
        printf("Child: pid:%d\n", getpid());
        exit(0);
    }
}

void func( int theSignal) 
{
    if( MY_SIGNAL == theSignal )
    {
        printf("the %d signal has been processed by %d!\n", MY_SIGNAL, getpid());
    }

    else
    {
        printf( "the %d signal is processed\n", theSignal );
    }
}

然后输出是:

the fork'd child pid:5099
Parent:signal 31 will be sent to child!
the 31 signal has been processed by 5099!
Child: pid:5099
the 17 signal is processed
child process terminated

清楚地显示子处理信号31(SIGUSR2)和父处理信号17(SIGCHLD)