The objective is the parent process should make a child one, the parent prints the even numbers between 1 to 100, the child prints the odd ones. This mechanism should be made using signals (the numbers should be in order obviously e.g. parent:0, child:1, parent:2...) I made the following code:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
for(int i=0; i<=100; i++){
if (i % 2 != 0){
printf("I am the child: %d\n", i);
}
}
} else {
kill(pid, SIGSTOP);
for(int i=0; i<=100; i++){
if(i % 2 == 0){
printf("I am the parent: %d\n", i);
kill(pid, SIGCONT);
}
}
wait(NULL);
}
return 0;
}
But the output isn't in the order it should be, the parent prints all of his numbers first, the child follows him. I was wondering if the SIGSTOP and SIGCONT aren't the suitable signals to be used, but there's no other logical solution.
Any suggestion would be helpful. Thank you.
Block on a signal and resume only when that signal is received. Regarding which signal to use, you could use any that can be blocked (any signal excluding SIGKILL
, SIGSTOP
). I used SIGRTMIN
because it is for application-defined purposes.
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
/* Block SIGRTMIN */
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGRTMIN);
if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0)
exit(1);
int signo;
/* Spawn a new child */
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
sigwait(&sigmask, &signo); // This is to make parent start first.
for(int i=1; i<=100; i=i+2){
printf("I am the child: %d\n", i);
kill(getppid(), SIGRTMIN); // Resume parent
sigwait(&sigmask, &signo); // Wait for parent
}
} else {
for(int i=0; i<=100; i=i+2){
printf("I am the parent: %d\n", i);
kill(pid, SIGRTMIN); // Resume child
if (i == 100) // Parent stucks at sigwait after printing 100.
break;
sigwait(&sigmask, &signo); // Wait for child
}
wait(NULL);
}
return 0;
}
We blocked SIGRTMIN in the parent but how does it gets blocked in the child?
According to signal(7)
man page.
A child created via fork(2) inherits a copy of its parent's signal mask; the signal mask is preserved across execve(2).