2010-11-16 26 views
0

以下处理为进程是代码片断:误差信号在linux

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

sig_atomic_t child1 ; 

sig_atomic_t child2 ; 

void child1_handler(int sig_num) 
{ 

    int ret ; 

if(sig_num == SIGUSR2) 
{ 
    printf("\n Recieved sigusr2 for child1\n"); 

    ret = kill(getppid() , SIGUSR2) ; 
    if(ret != 0) 

     kill(getpid() , SIGTERM); 
} 
else if(sig_num == SIGUSR1) 
{ 
    /* child 1 does something */ 
    printf("\n Recieved sigusr1 for child1\n"); 
    printf("\n child 1 is doing \n"); 

    kill(child2 , SIGUSR2); 
} 
} 

void child2_handler(int sig_num) 
{ 
if(sig_num == SIGUSR2) 
{ 
    /* child2 does somethign */ 
    printf("\n Recieved sigusr2 for child2\n"); 
    printf("\n child2 is doing \n"); 

    kill(child1 , SIGUSR2); 

    kill(getpid() , SIGTERM); 
} 
} 

void parent_handler(int sig_num) 
{ 
int ret ; 
if(sig_num == SIGUSR2) 
{ 
    printf("\n Recieved sigusr2 for parent\n"); 

    ret = kill(child1 , SIGUSR1) ; 
    if(ret != 0) 
    { 
     /* parent does something */ 

     printf("\n Parent does something \n"); 
     exit(0); 
    } 
} 
    } 


    int main() 
    { 
struct sigaction sa_parent , sa_child1 , sa_child2 ; 
pid_t temp_id1 , temp_id2 ; 
int temp ; 

memset(&sa_parent , 0 , sizeof(sa_parent)) ; 
memset(&sa_child1 , 0 , sizeof(sa_child1)) ; 
memset(&sa_child2 , 0 , sizeof(sa_child2)) ; 

/* parent */ 

printf(" \n Inside parent \n"); 

sa_parent.sa_handler = &parent_handler ; 
sigaction(SIGUSR2 , &sa_parent , NULL); 

temp_id1 = fork() ; 

if(temp_id1 == 0) 
{ 
    child1 = getpid() ; 

    /* child1 */ 

    printf("\n inside child1 \n"); 

    sa_child1.sa_handler = &child1_handler ;  
    sigaction(SIGUSR1 , &sa_child1 , NULL) ; 
    sigaction(SIGUSR2 , &sa_child1 , NULL) ; 

    temp_id2 = fork() ; 

    if(temp_id2 == 0) 
    { 
     child2 = getpid() ; 

     /* child2 */ 

     printf("\n inside child2 \n"); 

     sa_child2.sa_handler = &child2_handler ; 
     sigaction(SIGUSR2 , &sa_child2 , NULL); 

     kill(child1 , SIGUSR2); 
    } 

    wait(&temp); 
} 

wait(&temp); 
return 0 ; 
    } 

我期待输出到描绘了第一

child1 is doing 
child2 is doing 
parent does something 

然而所产生的输出是如下面给出的。 。

Inside parent 
inside child1 
inside child2 
Recieved sigusr2 for child1 
Recieved sigusr2 for parent 
Recieved sigusr1 for child1 
child 1 is doing 
Recieved sigusr2 for child1 
User defined signal 1 

[ what is going wrong ? ] 

请忽略“接收到的标志”和“内部...”行,因为它们是为了标记loca代码中的tions。

+1

为什么你的代码以明显随机的方式缩进? – caf 2010-11-16 23:41:30

+1

你可能会考虑使用sigemptyset()而不是memset()。 memset()不保证排除所有信号。这是一个附注,与你的问题不太相关,但我想我会指出。 – 2010-11-17 00:11:29

回答

1

变量child1未在父进程中设置。因此,父进程中的kill()调用将指示当前进程组中的所有进程。

此外,在信号处理程序中使用printf()很少安全。这里看起来几乎是安全的,因为中断的功能是wait(),它是异步信号安全的,但通常它是不安全的。

waitpid()wait4()优先于wait(),因为它们让您等待特定的子进程。

+0

与此类似,child1不保存child2的pid。 – 2010-11-16 23:50:53

0

这三个进程的地址空间不以任何方式共享。所以变量'child1'和'child2'在进程之间是不同的。因此,当第一个孩子设置“child1”时,它不会影响父级中的“child1”变量。所以当父母发送一个信号给'child1'时,它会被发送到0--整个进程组。