-1

I have written code in C as follows

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

int main()
{
    int id;
    id = fork();
    if(id == 0)
        printf("Child Process\n");
    else if(id > 0)
        printf("Parent Process\n");
    else
        perror("Unable to fork\n");
        
    return 0;
}

Output as shown in ubuntu 20 OS

Parent Process
Child Process

I am expecting that child process should be written first as after fork() is called child process's printf() will be printed on screen and after that parent's printf() will be printed but reverse is printed actually. Please help me why child process's printf() is not printed first as id is 0 in child process.

  • 4
    The two processes after the fork are independently scheduled. They may run in either order. – Jonathan Leffler Jan 01 '22 at 13:59
  • Isn't it like when we call fork() control goes to child process and after child process is done executing it's instructions, control goes back to parent process. The reason for this behaviour is like c executes its instructions one by one from top to bottom. Am I missing something? – Albert Einstein Jan 01 '22 at 14:06
  • 1
    "*when we call fork() control goes to child process and after child process is done executing it's instructions, control goes back to parent process*" - no. Those processes are run in parallel. The order of instruction withing a single C code is irrelevant here. – Fureeish Jan 01 '22 at 14:08
  • 1
    Absolutely not, @AlbertEinstein. `fork()` creates an independent process that, barring explicit provisions to the contrary, runs in parallel with the original process. – John Bollinger Jan 01 '22 at 14:08
  • In general, the two processes run for a long time, doing separate work. Think of a shell running a pipeline like `who -u | sort -k1,1 -k3,4`. The `who` command produces lines containing login details; the `sort` command reads all of the output from `who` while `who` is running, and then sorts and prints the data. Other pipelines may have many processes generating and processing megabytes of data; the processes must run concurrently — they cannot wait until a predecessor is complete. All else apart, pipes only hold a finite amount of data (once it was typically 5 KiB; now it's usually 64 KiB). – Jonathan Leffler Jan 01 '22 at 14:39

1 Answers1

4

The processes may run in either order as they are independently scheduled (as said by Jonathan Leffler in the comments), and usually also run in different CPU cores. Think of them like two different browser windows that can play video/audio at the same time.

Maybe sleep(1); the parent process after fork(); if you have any data that the child process must insert before the parent process reads it. (or any other reason you have).

In theory, it is still not guaranteed that the child process will run before the parent process even with the parent process waiting for 1 second.

Also, why would you want the child process to run before the parent process?

Isn't it like when we call fork() control goes to child process and after child process is done executing it's instructions, control goes back to parent process. The reason for this behaviour is like c executes its instructions one by one from top to bottom. Am I missing something?

It is a different process!!! Once the child process starts up, it has a totally different execution thread, and fork() returns back to the parent process and the child process runs on its own. And this is why when you call exit(1); on the parent process, the child process won't exit.

As siride suggested: you can use wait(), use this if you want to make the parent process only run after the child process:

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

int main()
{
    int id;
    id = fork();
    if(id == 0) {
        printf("Child Process\n");
    } else if(id > 0) {
        wait(id); // waits until child process finishes doing its work
        printf("Parent Process\n");
    } else {
        perror("Unable to fork\n");
    }
        
    return 0;
}
Example person
  • 3,198
  • 3
  • 18
  • 45
  • Isn't it like when we call fork() control goes to child process and after child process is done executing it's instructions, control goes back to parent process. The reason for this behaviour is like c executes its instructions one by one from top to bottom. Am I missing something? – Albert Einstein Jan 01 '22 at 14:07
  • @AlbertEinstein, no. see my edit – Example person Jan 01 '22 at 14:07
  • With Reference to https://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html . They said it's the problem due to printf(), and child process will run first – Albert Einstein Jan 01 '22 at 14:09
  • @AlbertEinstein, I do not see anything on that page saying that the child will run first. In fact, it appears to take some care to *avoid* saying such a thing. It definitely does not say that the child will run to completion before the `fork()` call returns in the parent. – John Bollinger Jan 01 '22 at 14:14
  • @Exampleperson , they have mentioned like why to use write() instead of printf() saying buffer problem. – Albert Einstein Jan 01 '22 at 14:18
  • @AlbertEinstein your mental model of how this works is wrong and you will not find a shred of documentation that supports you. When you call fork() the OS creates an entirely separate program that runs at its own rate. Period. If you want sequential behavior either don't use fork or have the parent call wait() on the child before proceeding with its own work. – siride Jan 01 '22 at 14:30
  • Ok, means the two process child and parent will run independently with concurrency, so with concurrency, it means two process will run simultaneously at same time or its like simultaneously not at same time but with context switching? – Albert Einstein Jan 01 '22 at 14:37
  • @AlbertEinstein — You might find some insight about buffering output at [`printf()` anomaly after `fork()`?](https://stackoverflow.com/q/2530663/15168). Using `write()` directly avoids the anomaly. It isn't a factor with the code shown in this question, though; there is no pending output before the `fork()` occurs. – Jonathan Leffler Jan 01 '22 at 14:42
  • @AlbertEinstein it depends on how many cores your computer has and where the OS decides to run each process. They might run truly concurrently if on different cores, or interleaved if on the same core. Multiprocessing is a complex topic. Its best to reason about your code as if the processes are truly running in parallel or, if interleaved, can run in any order. If you want stronger guarantees, look into synchronization primitives like mutexes or IPC. – siride Jan 01 '22 at 15:10