-1

I'm doing a program with the objective of creating a process within a process 3 times(get a child process(1), a grand child process(2) and a grand grand child(3) process) and do actions in each process in reverse order of the creation order. Which means first I do the actions of (3) then the actions of (2) then of (1) then of the parent process. But the output is weird like doing 6 printfs and multiple processes saying they have the same pid.

Code:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
    pid_t mypid = getpid();
    pid_t child1_pid=fork();


    pid_t child2_pid=-1; //waiting for child1 to fork
    pid_t child3_pid=-1; //waiting for child2 to fork

    int status;

    if(child1_pid==0)
    {
        mypid=getpid();
        child2_pid=fork()

        if(child2_pid==0)
        {
            mypid=getpid();
            child3_pid=fork()

            if(child3_pid==0)
            {
                mypid=getpid();
                printf("3: Im %ld and my parent is %ld\n", mypid, getppid());
            }
            wait(&status);
            printf("2:Im %ld and my parent is %ld\n", mypid, getppid());
        }
        wait(&status);
        printf("1:Im %ld and my parent is %ld\n", mypid, getppid());
    }
    else
    {
        wait(&status);
        printf("\nIm the father and my pid is %ld\n", mypid);
    }
    return 0;
}   

What I'm asking is what I'm doing wrong and where is my logic incorrect and maybe point me to some reading in the web. Thanks in advance.

Joaquim Ferrer
  • 603
  • 6
  • 23
  • the posted code shows 6 compiler warnings and an error. Always enable all warnings when compiling, then fix those warnings. (for gcc, at a minimum use: `-Wall -Wextra -pedantic` ) Please fix the compile problems, then post an edit (don't change the currently posted code) with the corrected code – user3629249 Oct 01 '15 at 22:43
  • the system function `fork()` has three kinds of return values 1) =0 means child is executing 2) >0 means the parent is executing 3) <0 means an error occurred. The code needs to check for all three conditions, rather than making assumptions. – user3629249 Oct 01 '15 at 22:47
  • the posted code seems to have some incorrect ideas about exactly which process is executing during each part of the code. Remember, the parent and fork'd processes are all running at any common points in the code after the specific process/child has been created. – user3629249 Oct 01 '15 at 22:49
  • you might try (for your own understanding) comment the code with exactly which process(s) is/are executing at each code block. – user3629249 Oct 01 '15 at 22:51

2 Answers2

1
if(child1_pid==0)
    {
        mypid=getpid();
        child2_pid=fork()

        if(child2_pid==0)
        {
            mypid=getpid();
            child3_pid=fork()

            if(child3_pid==0)
            {
                mypid=getpid();
                printf("3: Im %ld and my parent is %ld\n", mypid, getppid());
            }
            wait(&status);
            printf("2:Im %ld and my parent is %ld\n", mypid, getppid());
        }
        wait(&status);
        printf("1:Im %ld and my parent is %ld\n", mypid, getppid());
    }

In this code the grand grand child will print 3 times: the printf inside its if and the outer 2 ones.

The grand child will print its printf and its outer one and so one.

Your new processes are continuing to execute the rest of your code normally which means it'll print the following printf's that exist in the code.

For the code to execute as you desire you must terminate execution in each grand child process and each father process must wait for its child to terminate prior to printing.

The following should work as you desire.

if(child1_pid==0)
{
    mypid=getpid();
    child2_pid=fork()

    if(child2_pid==0)
    {
        mypid=getpid();
        child3_pid=fork()

        if(child3_pid==0)
        {
            mypid=getpid();
            printf("3: Im %ld and my parent is %ld\n", mypid, getppid());
            return 0;
        }
        waitpid(child3_pid,&status,0);
        printf("2:Im %ld and my parent is %ld\n", mypid, getppid());
        return 0;
    }
    waitpid(child2_pid,&status,0);
    printf("1:Im %ld and my parent is %ld\n", mypid, getppid());
}else
{
    waitpid(child1_pid,&status,0);
    printf("\nIm the father and my pid is %ld\n", mypid);
}
return 0;

The function waitpid waits for the pid specified process to finish. The function declarations is the following:

pid_t waitpid(pid_t pid, int *status,int options);

The value 0 for the options parameter used in the code shown before indicates that it should the default behavior (wait for the termination of the process).

DMH
  • 182
  • 1
  • 2
  • 17
  • Yes that's the exatc problem! the grand grand child will print 3 times and so on because it doesnt stop in it's if block! thank you very very much! – Joaquim Ferrer Oct 02 '15 at 10:35
0

Adding to DMH answer, you should also use write() instead of printf, as printf is buffering the output, so the results might be mixed at the end of the output .

http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html

CiceroDev
  • 31
  • 2