tags:

views:

201

answers:

4

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
A: 

i ask how can i get

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
Yakup OZDEN
This is a place for answers only, update your question when you have something to add or change. And your question is still not clear, at least to me. Don't expect people to read your mind, use words and try to explain what's the difference between what you got, and what you need. What's missing? What's wrong?
jweyrich
+2  A: 
[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()
Cristina
i'm confused.Where will i put the wait()
Yakup OZDEN
fork() will be called twice where is the root process.i want to get 4 child and 5 child2 it gives me 20 child2
Yakup OZDEN
That's because all `child` are returning from `forkChildren` and running `forkChildren2`. So you get 4 * 5 = 20. You have to change the way you fork, or put a condition to run `forkChildren2` only in the parent process.
jweyrich
A: 

ok i'll add semaphores later for simulating

what if i want to get only the output below .

[ozdeny@hyperion ~]$ ./fork 4 5
I am a child: 1 PID: 22949
I am a child: 2 PID: 22950
I am a child: 3 PID: 22951
I am a child: 4 PID: 22952
I am a child2: 1 PID: 22953
I am a child2: 2 PID: 22954
I am a child2: 3 PID: 22955
I am a child2: 4 PID: 22956
I am a child2: 5 PID: 22957
Yakup OZDEN
+2  A: 

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;
}
jweyrich
thanks for help.It works correcttly.What if i wan't to simulate childs.Let them work different order.sleep function can't do it. should i try using semaphores
Yakup OZDEN
What do you mean by _work in different order_? Thread are independent of each other. Semaphores are used for synchronisation. I might be able to help if you give a good description of what you want to do.
jweyrich
in fact,i'm trying to write multiple producer single consumer simulation.in forkChildren add_a() will called in forkChildren2 cosume_a will called.if i put this functions firsty add_a wfunction called by number of children of first fork.and then consume_a() function called by number of children of second fork.i want to simulate like example.(it may work different order)add_a()consume_()add_a()add_a()consume_a()
Yakup OZDEN
Thanks, now I understand. You don't need to worry about the order they'll be executed, but you need semaphores to signal the consumer threads that one item is available on the queue/list/whatever. Whenever the producer puts a item in the container, it signals the consumers to wakeup, and process the item. Doing this, you avoid processor-consuming loops. For more informations, read http://en.wikipedia.org/wiki/Producer-consumer_problem
jweyrich