My QNX class notes has this example, I cant seem to figure out how my prof came up with that output. Can anyone explain this to me thoroughly?
When this program runs the parent process has a PID of 1234 and the child process has 5678.
Output 5678: counter = 0 1234: counter = 10
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
/*
* getpid() - returns the current processes pid.
* getppid() - returns the parent processes pid.
*/
int counter = 0;
void signal_handler(int signo)
{
counter++;
}
int main(int argc, char *argv[]) {
int i = 0;
int rv;
struct sigaction sa;
sa.sa_handler = signal_handler;
//queue signals.
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
switch(fork())
{
case 0:
for(i = 0; i < 10; i++)
{
kill(getppid(), SIGUSR1);
}
break;
default:
wait(&rv);
break;
}
printf("%d: counter = %d\n", getpid(), counter);
return 0;
}
The fork
creates a child process with its own copy of counter
.
The kill
, called by the child process, is sending a SIGUSR1
to the parent process because it is using getppid()
to get the pid.
The parent process is either blocked in the wait
, or somewhere between the fork
and the wait
. For each SIGUSR1
sent by the child, the parent will jump into the signal handler, increment its copy of counter
, and return to whatever it was doing.
In general, wait
can return with an EINTR
error if a signal is handled while it is waiting. Setting SA_RESTART
in sa.sa_flags
ensures that system call will be restarted, but here it assumes that the wait
will not be interrupted by the signal (does QNX guarantee this?).
The child's copy of counter
is not affected. The wait
causes the parent to block until the child has exited. The child thus prints its value of counter
, which is 0
, and exits, the parent wakes from the wait
and prints its value of counter
, which is 10
.