2010-11-16 99 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--整個進程組。