简体   繁体   中英

Parent process runs twice after receiving signal

I wrote a program, where the parent process prints out 5 ( lottery ) numbers, received from the parameter list. Then the child process generates 5 random numbers, and if one of these numbers are equal to the parameters, it sends SIGUSR1, else SIGUSR2 signal to the parent process. If i do not use signals, just simply print the answers from the child, the code works fine. But with the signals, the parent process runs twice or at least it's content is printed out twice. Can you please explain this behavior to me? Thanks in advance!

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

void handler(int signumber){
        printf("The child got a hit, my pid: %i\n", getpid());
}

void handler2(int signumber){
        printf("The child had no hit!\n");
}

int main(int argc, char* argv[])
{
    signal(SIGUSR1,handler);
    signal(SIGUSR2,handler2);

    int status, child;
    int num1 = atoi(argv[1]);
    int num2 = atoi(argv[2]);
    int num3 = atoi(argv[3]);
    int num4 = atoi(argv[4]);
    int num5 = atoi(argv[5]);

    if ( num1<0 || num1>45 || num2<0 || num2>45 || num3<0 || num3>45 || num4<0 || num4>45 || num5<0 || num5>45 ){
        perror("We need 5 numbers in range of 0 and 45");
        exit(1);
    }

    child = fork();

    if(child>0){ //parent
        printf("The numbers: %i, %i, %i, %i, %i. my pid: %i \n", num1,num2,num3,num4,num5,getpid());
    } else{
        int rnd,i,isAnyHit;
        isAnyHit = 0;
        srand(time(NULL) * (getpid())); 
        for ( i=0;i<5;i++ ){
            rnd = ((rand()%45)+1);
            if ( rnd == num1 || rnd == num2 || rnd == num3 || rnd == num4 || rnd == num5 ){
                kill(getppid(),SIGUSR1);
                isAnyHit++;
            }   
        }
        if ( isAnyHit == 0 )
            kill(getppid(),SIGUSR2);
    }
    return 0; 
}

I made some code changes, and it seems to work for me.

#include <stdio.h>    
#include <stdlib.h>    
#include <unistd.h>     
#include <sys/wait.h>     
#include <errno.h>     
#include <signal.h>    
#include <time.h>    


void handler(int signumber){    
  printf("Got signal %d at %i\n", signumber, getpid());    
}    

int main(int argc, char* argv[])    
{    
  signal(SIGUSR1,handler);    
  signal(SIGUSR2,handler);    

  int status, child;    
  int num1 = atoi(argv[1]);    
  int num2 = atoi(argv[2]);    
  int num3 = atoi(argv[3]);    
  int num4 = atoi(argv[4]);    
  int num5 = atoi(argv[5]);    

  if ( num1<0 || num1>45 || num2<0 || num2>45 || num3<0 || num3>45 || num4<0 || num4>45 || num5<0 || num5>45 ){    
    perror("Invalid numbers\n");    
    exit(1);    
  }    

  child = fork();    

  if(child>0){ //szülő    
    printf("In the parent - child pid is %i, parent pid is %i\n", child, getpid());    
    sleep(1000);    
  } else{    
    printf("In the child - child pid is %i, parent pid is %i\n", getpid(), getppid());    
    int rnd,i,isAnyHit;    
    isAnyHit = 0;    
    srand(time(NULL) * (getpid()));     
    for ( i=0;i<5;i++ ){    
      rnd = ((rand()%45)+1);    
      printf("Checking %i against numbers\n", rnd);    
      if ( rnd == num1 || rnd == num2 || rnd == num3 || rnd == num4 || rnd == num5)){    
        printf("Matched %i\n", rnd);    
        kill(getppid(),SIGUSR1);    
        isAnyHit++;    
      }       
    }    
    if ( isAnyHit == 0 )    
      kill(getppid(),SIGUSR2);    
  }    

  printf("PID %i is ending\n", getpid());    
  return 0;     
}  

Following output:

$ ./a.out 1 2 3 4 5
In the parent - child pid is 20401, parent pid is 20400
In the child - child pid is 20401, parent pid is 20400
Checking 6 against numbers
Checking 18 against numbers
Checking 15 against numbers
Checking 42 against numbers
Checking 4 against numbers
Matched 4
PID 20401 is ending
Got signal 10 at 20400
PID 20400 is ending

But if 2 numbers match:

$ ./a.out 1 2 3 4 5
In the parent - child pid is 20493, parent pid is 20492
In the child - child pid is 20493, parent pid is 20492
Checking 2 against numbers
Matched 2
Checking 5 against numbers
Matched 5
Checking 13 against numbers
Got signal 10 at 20492
Checking 36 against numbers
Checking 19 against numbers
Got signal 10 at 20492
PID 20493 is ending
PID 20492 is ending

I get 2 SIGUSR1 (10).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM