This seems tailor-made for a semaphore. Specifically, this is easy to implement with "System V semaphores". See semget(2)
and semop(2)
.
The idea is that you obtain a semaphore in the parent, initialize its value to N
, then have each child as it's "ready" decrement the value by 1. All children wait for the result to become 0. Voila.
Here's a sample program
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define N 5
int main(int ac, char **av)
{
int i, n, sem_id;
sem_id = semget(IPC_PRIVATE, 1, 0777);
struct sembuf buf;
buf.sem_num = 0;
buf.sem_flg = 0;
// Initialize semaphore value to N
buf.sem_op = N;
n = semop(sem_id, &buf, 1);
// All children will do the same thing:
// decrement semaphore value by 1
// wait for semaphore value == 0
for (i = 0; i < N; ++i) {
if (fork() == 0) {
printf("Child %d (%d) started\n", i, getpid());
sleep(i + 1); // Sleep awhile.
buf.sem_op = -1;
n = semop(sem_id, &buf, 1);
buf.sem_op = 0;
n = semop(sem_id, &buf, 1);
printf("Child %d (%d) done\n", i, getpid());
return 0;
}
}
return 0;
}