Multiple child process
Asked Answered
E

5

22

can someone help me about how to create multiple child processes which have the same parent in order to do "some" part of particular job?

for example, an external sorting algorithm which is applied with child processes; each child process sorts a part of data and finally the parent merges them..

EDIT: Maybe I should mention the forking multiple child processes with loop..

Emboss answered 18/5, 2009 at 7:38 Comment(2)
wouldnt you be better off with threads?Forbid
well, that may be right.. but i need to practice the multiple forking() which means multiple child process..Emboss
M
67

Here is how to fork 10 children and wait for them to finish:

pid_t pids[10];
int i;
int n = 10;

/* Start children. */
for (i = 0; i < n; ++i) {
  if ((pids[i] = fork()) < 0) {
    perror("fork");
    abort();
  } else if (pids[i] == 0) {
    DoWorkInChild();
    exit(0);
  }
}

/* Wait for children to exit. */
int status;
pid_t pid;
while (n > 0) {
  pid = wait(&status);
  printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
  --n;  // TODO(pts): Remove pid from the pids array.
}
Marchpast answered 18/5, 2009 at 8:7 Comment(7)
i didn't really get the second part(wait for children to exit).. what does status mean? is that a child process property?Emboss
Status is the exit status of the child process. It depends on the exit(...) value, or if the process is killed by a signal, then it depends on the signal number. See this for more: linux.die.net/man/2/waitMarchpast
one question, are you forking from the same root parent or from each child?Lowrie
@Chin Boon: Since fork() returns 0 for the child, the answer to your question (are you forking from the same root parent or from each child?) is yes.Marchpast
hi pts! I was wondering why the children processes don't fork themselves new process. I have just noticed the call to exit(0). I want to ask you: if that call was not present there, the children would have called fork() as well as the parent process, wouldn't they? I mean, the first child process would have i = 0 and call 10 forks... I mean, the children would enter the for loop, no??Nitin
@flyer88: Yes, they would.Marchpast
@flyer88: As I wrote in an earlier comment repy, fork() returns 0 for the child process only. In my code the if checks the return value of fork(), so the child only runs DoWorkInChild() and exit(0). Thus it will never reach a code path which calls fork().Marchpast
D
7

If you want to launch several forks, you should do it recursively. This is because you must call fork from the parent process. Otherwise, if you launch a second fork, you will duplicate both parent and first child process. Here's an example:

void forker(int nprocesses)
{
    pid_t pid;

    if(nprocesses > 0)
    {
        if ((pid = fork()) < 0)
        {
            perror("fork");
        }
        else if (pid == 0)
        {
            //Child stuff here
            printf("Child %d end\n", nprocesses);
        }
        else if(pid > 0)
        {
            //parent
            forker(nprocesses - 1);
        }
    }
}
Denbighshire answered 13/10, 2016 at 9:23 Comment(1)
Doing such recurion consumes stack space unnecessarily (not only in the parent, but also in the children). Depending on the number of children and the stack limit, this solution.may crash. To fix it, use a loop instead of recursion.Marchpast
J
5

I think it would be worth pointing out why threads are more appropriate here:

As you are trying to do a "part" of the job in parallel i assume that your program needs to know about the result of the computation. fork()s of a process don't share more then the initial information after fork(). Every change in one process is unknow to the other and you would need to pass the information as a message (e.g. through a pipe, see "man pipe"). Threads in a process share the same adress space and therefor are able to manipulate data and have them visible toeach other "immediatly". Also adding the benefits of being more lightweight, I'd go with pthreads().

After all: You will learn all you need to know about fork() if you use pthreads anyway.

Jeer answered 18/5, 2009 at 8:7 Comment(1)
On the other hand, if you work is user supplied, you would want to do it in a new process for crash protection.Equip
O
4

You can do this with fork. A given parent can fork as may times as it wants. However, I agree with AviD pthreads may be more appropriate.

pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild > 0)
{
  // In parent
  secondChild = fork();
  if(secondChild > 0)
  {
    // In parent
  }
  else if(secondChild < 0)
  {
    // Error
  }
  else
  {
    // In secondChild
  }
}
else if(firstChild < 0 )
{
  // Error
} 
else
{
  // In firstChild
}
Ozzie answered 18/5, 2009 at 7:48 Comment(1)
shouldn't we also consider the case, where xxxChild < 0 will raise an error? I think (xxxChild > 0) will be a more appropriate one...Florrie
G
-1
#include<stdio.h>
#include<unistd.h>
#include <stdlib.h>

int main() {
    int n = 3;   //How many child process to create from 1 parent?
    printf("parent process running, pid of the parent process is 
%d\n",getpid());
    for(int i=0; i<n; i++) {
        pid_t return_value;
        return_value = fork();
        
    if(return_value <0){
        printf("fork() has failed during child creation");
        exit(1);
        }
    else if(return_value == 0){
        printf("Child created successfully,at the instance child process is running on CPU, pid of the child process is %d\n", getpid());
        exit(0);
    }
    }
    for(int i=0; i<n; i++){
        //Parent process waits for child process to finish execution
        int status;
        wait(&status);
    }
    printf("parent process running again after creation of 3 child, pid of the parent process is %d\n", getpid());
    return 0;
}


/*>Output

parent process running, pid of the parent process is 732
Child created, pid of the child process is 736
Child created, pid of the child process is 738
Child created, pid of the child process is 737
*/
Gironde answered 8/11, 2023 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.