Reputation: 11
I am studying about processes in operating systems. I came up with a question in which I have to create two child processes to do similar task using fork and wait. After the parent fork the first child, that child will wait until parent fork another one and the second child finish its job.
Second child 1 3 5 7 9 11 13 15 17 19 second child dies First child 2 4 6 8 10 12 14 16 18 20 first child dies
I've been trying various ways but I couldn't make the first child wait until the second child finishing its job. Does anybody know how to do it? Thanks
Upvotes: 0
Views: 2121
Reputation: 3123
Given the example you've provided, I'm thinking of two problems that you need to deal with using a combination of system calls and C-library calls:
Solving the first problem is dependent on the operating system that you want to implement this for. Typically POSIX compliant operating systems will provide a few mechanisms that can be used for this. These mechanisms are likely to include process control, pipes, sockets, signals, semaphores, shared memory, file operations, and message passing. Non-POSIX compliant systems may also have some of these mechanisms or similar that can be used but for the sake of this answer I'll stick with the target OS being a POSIX-compliant Unix-like OS.
The second problem is more simply just a matter of knowing how to flush the output stream that the code uses. The C-library standard IO stream and the fflush
call can serve for this.
Here's some code I whipped up that puts this together, compiles for me, and gives the output you showed:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int use_sig = SIGUSR1;
pid_t child1 = fork();
if (child1 == 0)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, use_sig);
int sig;
do
{
sigwait(&set, &sig);
} while (sig != use_sig);
printf("First child ");
printf("2 4 6 8 10 12 14 16 18 20");
printf(" first child dies");
fflush(NULL);
return 0;
}
pid_t child2 = fork();
if (child2 == 0)
{
printf("Second child ");
printf("1 3 5 7 9 11 13 15 17 19 ");
printf("second child dies ");
fflush(NULL);
kill(child1, use_sig);
return 0;
}
for (;;)
{
int status;
pid_t pid = wait(&status);
if (pid == child1)
{
child1 = 0;
}
else if (pid == child2)
{
child2 = 0;
}
if (child1 == 0 && child2 == 0)
{
break;
}
}
printf("\n");
exit(EXIT_SUCCESS);
}
Upvotes: 0
Reputation: 11
These are not optimal, but will do the trick :
First, option use a shared object :
- You can use mmap to create a shared memory area, (see man mmap)
- You can use shmget and shmat function family
- Hence you'll get each other PID and be able to use wait (man 2 wait)
Second option:
- The parent knows the PID of both children.
- The parent will send signals to both children, one by one. (see man 2 kill (and don't send KILL signal, please))
- Each child will have a custom parent, and do something with this signal.
Upvotes: 1