简体   繁体   中英

How to make a process continue it's execution when it's waiting a signal with pause() and it doesn't recieve it

I'm new to the forum and i've been googling and searching here my problem but didn't find it. Anyway i'm not very expert in searching in the forum so please excuse me if this has already been answered. Ok let's get to the point: i'm doing a small project for college where i have the following code written in C:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int ARB,A,B,X,Y,Z,i;

void senyal(){ //signal USR1 method
  if(getpid()==A){
    printf("I'm A process, I've received the signal\n");
    system("pstree");
   }

  else if(getpid()==B){
    printf("I'm B process, I've received the signal\n");
    system("pstree");
  }
  else if(getpid()==X){
    printf("I'm X process, I've received the signal\n");
    execlp("ls", "ls", "-al", "*.c", NULL);
  }
  else if(getpid()==Y){
    printf("I'm Y process, I've received the signal\n");
    execlp("ls", "ls", "-al", "*.c", NULL);
  }
}

int main (int argc, char *argv[]){
 char p=argv[1][0];
 int num=(int)p;

  pid_t pid;
  pid_t pid2;
  pid_t pid3;
  ARB=getpid();
  pid=fork(); //Creates father ARB and A child
    if(pid==-1){
        printf ("Error");
        }
    else if(pid==0){ // A child
        printf ("I'm A process: my pid is %d. My father is %d \n",getpid(), ARB);
        A=getpid();
     if(num==65||num==97){
       num=A;}
    pid2=fork(); //A is the father and creates B child
          if(pid2==-1){
      printf ("Error2");}
          else if(pid2==0){// B child 
        B=getpid();
         if(num==66||num==98){
           num=B;}
        printf("I'm B process , my pid is %d. My father is %d. My grandfather is %d \n",getpid(),getppid(),ARB);
        pid3=fork();//Creates X
          switch(pid3){
        case -1: printf("Error3");
             break;
        case 0:  printf("I'm  X process, my pid is %d. My father is %d. My grandfather is %d. My great grandfather is %d\n",getpid(),getppid(),A,ARB);
             X=getpid();
              if(num==88||num==120){
                num=X;}
             signal(10,senyal);
             printf("I'm X (%d) and I die\n",X);
             exit(X);
             break;
        default: 
             break;
          }
       pid3=fork();//Creates Y  
          switch(pid3){
        case -1: printf("Error no he podido crear el proceso hijo\n");
             break;
        case 0:  printf(I'm  Y process, my pid is %d. My father is %d. My grandfather is %d. My great grandfather is %d\n",getpid(),getppid(),A,ARB);
                 Y=getpid();
              if(num==89||num==121){
                num=Y;}
             signal(10,senyal);
             printf("I'm Y (%d) and I die\n",Y);
             exit(Y);
             break;
        default: 
              break;
          }
          pid3=fork();//Creates Z
           switch(pid3){
        case -1: printf("Couldn't create children proccess\n");
              break;
        case 0:  printf("I'm  Z process, my pid is %d. My father is %d. My grandfather is %d. My great grandfather is %d\n",getpid(),getppid(),A,ARB);
             Z=getpid();
             printf("I'm Z (%d) and I die\n",Z);
             sleep(argc); //

             kill(num,SIGUSR1);//sends a signal to any of the other process (A/B/X/Y)
             exit(Z);

             break;
        default: 
             break;
          }
        wait();//wait for the childrens' death
        wait();
        wait();
        printf("I'm B(%d) and I die\n",B);
        exit(B);//B's death
      }

          else{//Father A
        signal(10,senyal);
        wait();//await B's death
        printf("I'm A (%d) and I die\n",A);
        exit(A); //A's death

      }

    }    
    else{//Padre ARB
       printf ("\nI'm the process arb: my pid is %d\n",getpid());   
       signal(10,senyal);
       wait();  //await A's death     
       }
wait();     




                printf("I'm arb (%d) and I die\n",ARB);
exit (0);//ARB's death

}

So basically what the code is supposed to do is create a proccess tree and then receive a parametrer which indicates the PID of the proccess that needs to recieve the signal of type USGR1 that the process Z is sending. My problem here is that i want every process to be prepared to receive the signal, but in the case the process doesn't recieve it (for example the process A is waiting and ready to receive the signal from Z but Z sends it to B) i don't know how to tell that process to go on and not get stuck in pause forever. That's basically it, sorry if i commited any grammar or explanation errors but i'm from spain by the way. Thanks to anybody willing to answer!

From the man page of pause():

DESCRIPTION

pause() causes the calling process (or thread ) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function.

So you need another thread that delays with sleep() or similar and sends the signal anyway after a while. Or use something else than pause, like sleep.

To wait for a signal or a timeout, use select , pselect , poll or ppoll .

The p versions are used for custom signal masks, which might be something you need, but in this case probably not.

These functions are designed to take sets of file descriptors, but they work perfectly well without any file descriptors at all.

it's been a while. Sorry for taking so long to answer and thanks again to everyone who answered, your advice was quite useful. So, i finally found a way to solve my problem. After trying with pause, sleep and a lot of stuff without really getting where i wanted i realised i could use the signal 'alarm'. I used the pause() command to make the processes wait for a signal, but this time i set a SIGALARM signal in the process Z which is supossed to throw a signal to the others. So, in any case when Z has thrown the signal and it's about to die, it throws an alarm which awakes every process from their pause state. This solved my problem, so i hope this post helps anyone else with this problem. Thank you all again guys!

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