2013-01-10 14 views
6

Nie jestem w stanie zrozumieć danych wyjściowych dla następującego programu. Zauważyłem, że po powrocie procesu potomnego proces rodzica nie śpi przez 3 sekundy przed oczekiwaniem(). Jeśli SIGCHLD jest ustawione na domyślną procedurę obsługi, to śpi przez 3 sekundy, wywołując oczekiwanie i powracając zgodnie z oczekiwaniami. Co się dokładnie tutaj dzieje?Opis SIGCHLD, gdy proces potomny kończy się

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

void handler(int sig) { 
printf("Iam in handler ...\n"); 
} 

main() { 

int status; 
pid_t pid; 

struct sigaction act; 
//act.sa_flags=SA_NOCLDSTOP; 
act.sa_handler=handler; 
sigaction(SIGCHLD,&act,NULL); 

if(!fork()) { 
printf("child process id is %d\n",getpid()); 
return 1; 
} 

printf("xxx ...\n"); 
sleep(3); 
pid = wait(&status); 
printf("process terminated is %d\n",pid); 

} 

output:: 

xxx ... 
child process id is 2445 
Iam in handler ... 
process terminated is 2445 

Odpowiedz

8

Po zakończeniu procesu potomnego SIGCHLD jest wysyłane do rodzica. W twoim przypadku przerywa to sleep i wygląda na to, że proces nie śpi.

Istota problemu: sleep nie jest ponownie uruchamiana po przerwaniu przez sygnał.

+0

dzięki za odpowiedź ur. Jeszcze jedna wątpliwość - czytałem z postów, że restartowanie wywołań systemowych jest uzależnione od jego implementacji, a niektóre wywołania systemowe w ogóle się nie uruchamiają. Czy to prawda? Czy ponowne uruchamianie wywołań systemowych jest takie samo, jak dwukrotne wywołanie tego samego połączenia? – Goutham

+0

@ Goutham to nie to samo. Pomyśl o tym jako o "sygnale, który stara się nie zwracać" EINTR "i tak, restartowanie sygnału jest w większości zależne od implementacji. – cnicutar

11

Z man for sleep():

sleep() sprawia, że ​​sen wątek wywołujący aż sekund sekundy upłynęły lub sygnał dotrze który nie jest ignorowany.

Przerwanie Twojego dziecka powoduje sygnał do przebudzenia.

Wartość zwracana z sleep():

Zero jeśli upłynął czas, na wniosek, lub liczba sekund w lewo, aby zasnąć, jeśli połączenie zostało przerwane przez obsługę sygnału.

Może być używany, jeśli chcesz pomóc "ukończyć" sen.

unsigned sleep_time = 3; 
... 
while((sleep_time = sleep(sleep_time)) > 0) {} 
pid = wait(&status); 
... 
Powiązane problemy