0

The following code outputs a series of processes, exactly what it does is:

                 _PARENT_
               /          \
              /            \
        child_2             child_3
       /       \            /      \
      /         \          /        \
     /           \        /          \
g_child_4    g_child_5  g_child_6    g_child_7

This is the output:

Process Pid: 929 PPid: 928 (position: 2).
Process Pid: 930 PPid: 928 (position: 3).
Process Pid: 931 PPid: 929 (position: 4).
Process Pid: 932 PPid: 929 (position: 5).
Process Pid: 934 PPid: 930 (position: 7).
Process Pid: 933 PPid: 930 (position: 6).

My question is, how can I get the grandchild_4 and 5 pass to child_2 their position values and child_2 sum it and pas it to parent? And same thing with grandchilds_6 and 7 passing their position values to child_3 and sum it to pass it to parent?

All I'm trying to get is to be able to print the sum of the position values of all grandchilds so at the output I can have:

Process Pid: 929 PPid: 928 (position: 2).
Process Pid: 930 PPid: 928 (position: 3).
Process Pid: 931 PPid: 929 (position: 4).
Process Pid: 932 PPid: 929 (position: 5).
Process Pid: 934 PPid: 930 (position: 7).
Process Pid: 933 PPid: 930 (position: 6).
Result 22.

Note: no pipes, FIFOs or maps can be used.
This is my code:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h> 
#include <math.h>

 /*
 * NUMBER OF LEVELS TO BE CREATED
 */
 #define NUM_LEVEL 2 

 /* 
 * Child launcher
 */
int launchChild(int nivel,int n){
    //sleep(1);
    if(nivel>0) printf("Process Pid: %d PPid: %d (position: %d).\n",getpid(),getppid(), n+1);

    if(nivel<NUM_LEVEL){         
        pid_t process = fork();//Child or parent?

        if(process!=0){// Parent
            process=fork();//Child or parent?

            if(process==0){//Child
                launchChild(nivel+1,2*n+2); 
                wait(NULL);
            }
        }
        else{//Child
            launchChild(nivel+1,2*n+1);
        }
        wait(NULL);
    }
}

/*
* Main function
*/
int main(void){
    launchChild(0,0);    
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42

3 Answers3

0

The general term for what you're looking for is interprocess communication. There are many ways to pull this off: shared memory, pipes, FIFOs, and more.

For your purposes, I might recommend creating a simple array in shared memory (see the man page for shmget). Each process can fill in a specific position in the array with its position, and then you can use a POSIX semaphore (see sem_wait and sem_post) to signal the parent process that the position has been filled in. The parent process can then access the array and see what position its child process occupies.

tonysdg
  • 1,335
  • 11
  • 32
  • It may be the way, but not for this simple piece of code. The exercise does not ask for any pipes, FIFOs, etc. Thank you anyway. –  Nov 23 '15 at 19:32
  • @krm76: Just a head's up - if there are limitations/restrictions related to the question, please include those in the question so they are taken into account :) – tonysdg Nov 23 '15 at 19:33
0

If the sums involved are all guaranteed to be tiny, as in your example, then the children can return them via their exit codes, which you can obtain via the status value filled in by wait() when you pass it a non-NULL pointer (use the WEXITSTATUS() macro to obtain the exit code from the status). This works only if you can be confident that none of the sums will exceed 127.

In the general case, you would probably establish a pipe for each child process by which it could write its result for the parent to read. You could also set up shared memory by which each child could communicate its result, but this is trickier to set up and use properly, and it obviates the sub-process tree structure that you've gone to such trouble to create.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • John this is very interesting, could you write an example please? –  Nov 23 '15 at 19:31
  • How about this one: http://stackoverflow.com/questions/12864265/using-pipe-to-pass-integer-values-between-parent-and-child/12864595#12864595 – John Bollinger Nov 23 '15 at 19:36
  • Shame, not working in my code. I´ll have to redo my code because I can't get it to work properly. –  Nov 26 '15 at 14:17
0

You need to use a semaphore, or some sort of shared memory. You have a block of shared memory, using a lock so only one process may access it at a time

A decent reference to shared memory: http://www.cs.cf.ac.uk/Dave/C/node27.html