2

I have the following 2 sets of code that output differently. [outputting to the terminal]

Code 1:

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

int main ()
{ 
    printf("before the fork\n");
    fflush(stdout);
    int pid=fork();
    printf("after the fork\n");

    if (pid == 0)  
    {
        sleep(1);
        printf("I'm child");
    }
    else   
    {
        wait();
        printf ("I'm parent");
    }
    exit(0);
}

Output 1:

before the fork
after the fork
after the fork
I'm child

Now only the printf after the fork is commented and we see the printf after wait() for the parent process works as expected.

Code 2:

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

int main ()
{ 
    printf("before the fork\n");
    fflush(stdout);
    int pid=fork();
    // printf("after the fork\n");

    if (pid == 0)  
    {
        sleep(1);
        printf("I'm child");
    }
    else   
    {
        wait();
        printf ("I'm parent");
    }
    exit(0);
}

Output 2:

before the fork
I'm childI'm parent

I am confused as in how the printf after the fork() messes up the output.

Note the following output too

Code 3:

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

int main ()
{ 
    printf("before the fork\n");
    fflush(stdout);
    int pid=fork();
    printf("after the fork\n");

    if (pid == 0)  
    {
        sleep(1);
        printf("I'm child");
    }
    else   
    {
        //wait();
        printf ("I'm parent");
    }
    exit(0);
}

Output 3:

before the fork
after the fork
I'm parentafter the fork
I'm child

Any idea why this discrepancy?

unixwait
  • 21
  • 2
  • Have you tried adding `\n` to the other `printf` or `fflush(stdout)` after the other prints? The stdout of the parent may not be flushed. – dlivshen Oct 03 '21 at 11:22
  • Is your output to a tty or to a regular file? – William Pursell Oct 03 '21 at 11:27
  • 2
    What is `wait()`? Typically, `wait` takes an argument. – William Pursell Oct 03 '21 at 11:28
  • @WilliamPursell the output is to the terminal – unixwait Oct 03 '21 at 11:29
  • @dlivshen have tried both of that. doesn't impact the result except some line breaks – unixwait Oct 03 '21 at 11:30
  • 2
    As @william-pursell wrote, `wait` typically gets an output parameter for the status. What `wait` are you using? – dlivshen Oct 03 '21 at 11:37
  • [Enable warnings and treat them as errors](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings). – n. m. could be an AI Oct 03 '21 at 13:18
  • 1
    If you've included the required header, which is ``, your code will not compile. Since you don't have a `wait` function declaration in scope, gcc automatically generates one (an incorrect one) for you. – yyyy Oct 03 '21 at 13:44
  • I don't know why your code doesn't work though. Despite of calling `wait` incorrectly, your code should still work, and it does work on my machiine. – yyyy Oct 03 '21 at 13:53
  • Actually it should not compile at all. And if it compiles because you disabled some warnings, you will still fail on linking stage. Anyway after the processes are closed, stdout is flushed so you should see everything on the stream, the order is not guaranteed though. The only scenario I can think about it does not happen is if parent silently crashes. Maybe check for coredumps? – Yuri Nudelman Oct 03 '21 at 14:32
  • 1
    @YuriNudelman C functions don't have name mangling, so argument types don't matter. Linking will succeed as long as the function name matches. – yyyy Oct 03 '21 at 15:05
  • @yyy thinking of it, you are right. And this may actually explain the behavior. Suppose, somehow, he managed to compile with wait without passing it an argument. As a result, the function will use whatever it has on stack, which may be garbage. In that case it is likely that the parent gets a segmentation fault, and crashes silently. This explains why there is no parent print. – Yuri Nudelman Oct 04 '21 at 06:56
  • @YuriNudelman I thought that's the reason, too. But after I tried that, I found that `wait` does not crash, instead it returns -1 with `errno` set to `EFAULT` when `int *wstatus` it non-writeable. I'm not sure if it depends on the version of glibc. – yyyy Oct 05 '21 at 03:43

1 Answers1

0

It's not because of the printf("after the fork\n"); that you get different output.

The reason is when fork() system call is invoked you create a child process. And the both the parent process and child process both are running concurrently. So we don't know which would get priority (maybe parent or child).

My output in a online compiler.

In code2, the child process got the preference and so it executes first, followed by parent process.

Also in code 3, wait() system call is invoked, so if parent process gets the preference , it gets executed till the wait(). After that the child process is executed and after termination of child process, the parent process continues from where it left.

refer this for more understanding

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
ABINESH
  • 43
  • 5
  • 2
    OP's asking why "I'm parent" doesn't present in output1 – yyyy Oct 03 '21 at 15:07
  • @yyyy I think its because of compiler, I am getting the `printf("after the fork\n");` in online compiler and my linux machine. – ABINESH Oct 04 '21 at 03:46