I am new to the fork() function in C and have been having some problems. I haven't been able to find an answer that I can understand. I have a parent process which takes input from the user to signal a child process to update a value. What I have below is a simplified version of the actual program. I understand that I am not checking return values or anything of the like.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void parentFunc(int *pid);
void childFunc(void);
void countSignal(int signo);
int count = 10000;
int main(void){
signal(SIGUSR1, countSignal);
int pid[3];
// create child processes
pid[2] = fork();
if(pid[2] > 0){
pid[1] = fork();
if(pid[1] > 0){
pid[0] = fork();
if(pid[0] > 0){
parentFunc(pid);
}
else childFunc();
}
else childFunc();
}
else childFunc();
return 0;
}
void parentFunc(int *pid){
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
int identifier;
while(1){
identifier = fgetc(stdin) - '0';
kill(pid[identifier-1], SIGUSR1);
}
}
void childFunc(void){
srand(getpid());
while(1){
count -= (rand() % (3001 - 1000) 1000);
sleep(5);
}
}
void countSignal(int signo){
signal(SIGUSR1, countSignal);
count = 2000;
printf("Child %d has been fed by Parent %d\n", getpid(), getppid());
printf("New count level: %d\n", count);
}
When a child receives a signal, does it then skip the sleep(5) function? The issue I am having is that every time I try to update a value it seems to add 2000 and then immediately subtract the random value instead of subtracting on 5 second intervals.
I would like it to receive signals to add 2000 at any interval but only subtract every 5 seconds. Thanks.
CodePudding user response:
When a child receives a signal, does it then skip the sleep(5) function?
Yes, if the signal is not ignored, it skips the remaining sleep duration. From man 3 sleep
, emphasis added:
DESCRIPTION
sleep() causes the calling thread to sleep either until the number of real-time seconds specified in seconds have elapsed or until a signal arrives which is not ignored.
RETURN VALUE
Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler.
With that in mind, consider the following snippet:
unsigned seconds = 5;
while (seconds)
seconds = sleep(seconds);
For more precision, consider man 2 nanosleep
.
Aside: man 7 signal-safety
is worth reading to understand what POSIX defines as safe to do inside of a signal handler (does not include calling printf
).
See also: sig_atomic_t