Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding SIGCHLD when the child process terminates

Tags:

c

linux

I am not able to understand the output for the following program. I observed that after the child process returns, parent process is not sleeping for 3 sec before wait(). If SIGCHLD is set to default handler, then it sleeping for 3 sec, calling wait and returning as expected. What is exactly happening here ??

# 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
like image 989
Gowtam Avatar asked Jan 10 '13 20:01

Gowtam


2 Answers

From the man for sleep():

sleep() makes the calling thread sleep until seconds seconds have elapsed or a signal arrives which is not ignored.

Your child terminating causes a signal to wake you up.

The return value from sleep():

Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler.

Can be used if you'd like to help you "finish" the sleep.

unsigned sleep_time = 3;
...
while((sleep_time = sleep(sleep_time)) > 0) {}
pid = wait(&status);
...
like image 153
Mike Avatar answered Sep 21 '22 12:09

Mike


When the child process dies a SIGCHLD is sent to the parent. In your case it interrupts the sleep and it looks as if the process doesn't sleep.

The gist of the issue: sleep isn't restarted when interrupted by a signal.

like image 43
cnicutar Avatar answered Sep 18 '22 12:09

cnicutar