Reputation: 29
I want to create a program in C, where I use fork() to create multiple children, then wait for all of them to finish and do parent code (only once). I tried using for loop and two forks but I there is a problem: either parent code isn't running at the end or children are not running parallel.
//Number of processes I want to create
int processes = 6;
pid_t *main_fork = fork();
if(main_fork ==0){
for(int i=0;i<processes;i++){
pid_t *child_fork = fork();
if(child_fork ==0){
// child code
exit(0);
}
else if(child_fork >0){
//And here is the problem, with the wait: children don't
//run parallel and if I delete it, the main parent code doesn't run
wait(NULL);
}else{
// Child fork failed
printf("fork() failed!\n");
return 1;
}
}
}else if(main_fork >0){
wait(NULL);
//Main parent code - here I want to do something only once after all
//children are done
}else{
// Main fork failed
printf("fork() failed!\n");
return 1;
}
If somebody could could fix my code, or write a better solution to this problem I would be so grateful!
Upvotes: 1
Views: 3098
Reputation: 2188
If you want all the children to run in parallel, you have to do the wait after all the children has been started. Otherwise you start a child, wait for it to finish, start a new one, wait for that to finish, start a third one, wait for the third one to finish, and so on...
So what you typically want to do is to start all the children and put all the pid_t
in an array, and when you are finished you may call wait()
for each pid_t
This is the simple, and good enough solution for your case.
Here is a sample code that you can fit to your problem:
pid_t children[processes];
for(int i=0; i<processes; i++)
{
pid_t child = fork();
if(child == 0)
{
// child code
....
// We call _exit() rather than exit() since we don't want to clean up
// data structures inherited from parent
_exit(0);
}
else if (child == -1)
{
// Child fork failed
fprintf(stderr, "myprog: fork failed, %s", strerror(errno));
// Do real cleanup on failure is to complicated for this example, so we
// just exit
exit(EXIT_FAILURE);
}
children[i] = child;
}
// Do something if you want to do something before you expect the children to exit
....
for(int i=0; i<processes; i++)
{
pid_t child = children[i];
int status;
waitpid(child, &status, );
// Do something with status
}
Naturally this is not a complete example that fits any situation. Sometimes you have to tell the children when they should exit. Other times the children are not started/stopped in one go, and you have to play with asynchronous events, and so on...
Upvotes: 2