Yakup OZDEN
Yakup OZDEN

Reputation: 21

Creating multiple process and simulation in C via fork()

i want to create multiple process groups which will call different functions.

i write the code below. firstly i want to get following output

./fork 4 5

 I am a child: 1 PID: 22330
 I am a child2: 1 PID: 22334
 I am a child: 2 PID: 22331
 I am a child2: 5 PID: 22338
 I am a child: 4 PID: 22333
 I am a child: 3 PID: 22332
 I am a child2: 2 PID: 22335
 I am a child2: 4 PID: 22337
 I am a child2: 3 PID: 22336

'

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void forkChildren (int nChildren) {
     int i;
     pid_t pid;
     for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
          /* error handling here, if needed */
        return;
        }
        if (pid == 0) {
           printf("I am a child: %d PID: %d\n",i, getpid());
           sleep (5);
        wait(NULL);
        return;
        }
     }
  }
 void forkChildren2 (int nChildren) {
      int i;
      pid_t pid;
      for (i = 1; i <= nChildren; i++) {
          pid = fork();
          if (pid == -1) {
            /* error handling here, if needed */
          return;
          }
          if (pid == 0) {
             printf("I am a child2: %d PID: %d\n",i, getpid());
             sleep (2);
             return;
          }
       }
   }

   int main (int argc, char *argv[]) {

      forkChildren (atoi (argv[1]));
      forkChildren2 (atoi (argv[2]));

     return 0;
  }

the code gives me the output

[ozdeny@hyperion ~]$ ./fork 4 5
I am a child: 1 PID: 22330
I am a child: 2 PID: 22331 
I am a child: 3 PID: 22332 
I am a child: 4 PID: 22333
I am a child2: 1 PID: 22334 
I am a child2: 2 PID: 22335
I am a child2: 4 PID: 22337 
I am a child2: 5 PID: 22338
[ozdeny@hyperion ~]$ I am a child2: 3 PID: 22336
I am a child2: 1 PID: 22339
I am a child2: 2 PID: 22340
I am a child2: 3 PID: 22341
I am a child2: 4 PID: 22342 
I am a child2: 5 PID: 22343
I am a child2: 1 PID: 22345
I am a child2: 2 PID: 22346
I am a child2: 3 PID: 22347
I am a child2: 1 PID: 22349
I am a child2: 2 PID: 22350
I am a child2: 1 PID: 22344
I am a child2: 2 PID: 22352
I am a child2: 3 PID: 22353
I am a child2: 4 PID: 22354
I am a child2: 5 PID: 22355
I am a child2: 3 PID: 22351
I am a child2: 4 PID: 22356
I am a child2: 5 PID: 22357
I am a child2: 4 PID: 22348
I am a child2: 5 PID: 22358

Upvotes: 1

Views: 4816

Answers (2)

jweyrich
jweyrich

Reputation: 32240

According to a comment you made at @Cristina's answer, the problem is that it's forking 20 child2 instead of only 5, as specified on the command-line argument. The cause is that each child process created by forkChildren is returning to main and calling forkChildren2. You get 20 (in fact 25) child2 because 4 (forkChildren) * 5 (forkChildren2) = 20, plus the 5 created by the parent process.

I added return values to the functions (to both, just to keep them similar), and a if condition to skip forkChildren2 if it's a child process.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int forkChildren(int nChildren) {
    int i;
    pid_t pid;
    for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
            /* error handling here, if needed */
            return -1;
        }
        if (pid == 0) {
            printf("I am a child: %d PID: %d\n",i, getpid());
            sleep(5);
            return 1;
        }
    }
    return 0;
}

int forkChildren2(int nChildren) {
    int i;
    pid_t pid;
    for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
            /* error handling here, if needed */
            return -1;
        }
        if (pid == 0) {
            printf("I am a child2: %d PID: %d\n", i, getpid());
            sleep(2);
            return 1;
        }
    }
    return 0;
}

int main(int argc, char **argv) {
    int ret;
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
        return EXIT_FAILURE;
    }
    ret = forkChildren(atoi(argv[1]));
    if (ret == 0)
        forkChildren2(atoi(argv[2]));
    // wait(...) for all pids here, if you wish
    return EXIT_SUCCESS;
}

Upvotes: 2

Cristina
Cristina

Reputation: 2001

[ozdeny@hyperion ~]$ I am a child2: 3 PID: 22336

If this is your problem this means that your root process exits earlier than it's child processes. Make the root wait for it's children processes with a waitpid()[1].

[1] http://linux.die.net/man/2/waitpid

LE: You put waitpid in the root process not the forked process.

LLE: Ok i finally got what you want to do and an idea came from jweyrich observation, it goes like so return the array of pids for its child processes and then terminate them from the root process.

The main should look like this:

int* child_pids
//mem allocation
forkChildren();
for each pid in child_pids
  kill(pid,*signal termination*)
forkChildren2()

Upvotes: 2

Related Questions