I have just some questions about the system calls signal, kill and the signal handler. I have this code:
int figlio=-1; int main(int argc,char* argv[]) int pid1,pid2,dormi,numero; float reciproco; signal(SIGUSR1,gestore); signal(SIGUSR2,gestore); numero=atoi(argv[1]); printf("Numero %dnn",numero); fflush(stdout); pid1=fork(); if(pid1>0) //PADRE { pid2=fork(); if(numero%2 == 0) kill(pid1,SIGUSR1); else kill(pid2,SIGUSR2); wait(NULL); wait(NULL); } if(pid1 == 0) //FIGLIO1 { //sleep(1); printf("%dn",figlio); if(figlio == 1) { numero=numero*numero*numero; fflush(stdout); printf("Ho eseguito il cubo %dn",numero); } else { pause(); if(figlio == 1) //Se il gestore di SIGUSR1 รจ partito { fflush(stdout); printf("Ciao dal figlio 1n"); } } printf("Figlio1 terminann"); exit(0); } if(pid2 == 0) //FIGLIO2 { if(figlio == 2) { dormi=numero; reciproco=(float)numero; reciproco=1/reciproco; fflush(stdout); printf("Ho eseguito il reciproco %fn",reciproco); sleep(dormi); fflush(stdout); printf("Mando un segnale a mio fratello %dn",pid1); kill(pid1,SIGUSR1); } else printf("Arrivederci e grazien"); printf("Figlio2 terminann"); exit(0); } return 0; } void gestore(int signo) { if(signo == SIGUSR1) figlio=1; else figlio=2; }
1) I don’t understand why the first printf in the first child, return -1 without a sleep(1) before…seems that the handler is executed after the beginning of the child.
2) When there is a kill to a child, after this, the scheduler works on the child or continue on the father?
3) The handler is executed when the kill is sent or when the scheduler works on the child?
Advertisement
Answer
After the
fork()
, the parent and child processes are in a race. There is no guarantee the parent will have a chance to issue the call tokill()
to the child before the child reaches theprintf()
call.If there are multiple processors, both processes can be running simultaneously. Otherwise, if the child is not currently running, Linux will set some internal state that the signal should be delivered to the child process when it next runs, and it will mark the process as runnable if it is not already.
If the child is currently running, the signal gets processed immediately. Otherwise, it is processed when the child next runs. The handler is run as a result of processing the signal.