-1

I wrote this little program to help me understand processes better:

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

int main()
{
    int pid;
    int i;
    if ((pid = fork()) == 0)
    {
        for (i = 0; i < 100; i++)
        {
            printf("child, pid = %d, i = %d\n", getpid(), i);
        }
    }
    else if (pid > 0)
    {
        for (i = 0; i > -100; i--)
        {
            printf("parent, pid = %d, i = %d\n", getpid(), i);
        }
    }
    else
    {
        perror("failed fork!\n");
        exit(1);
    }
    return 0;
}

When i actually run the program i was surprised to see the output. Parent process started first which could also happen the other way around, right? In my machine it seems like it always chooses the parent. But what surprised me was that process once started couldn't finish outputting all i values. Why is this? Is the time that is given to a process that small? Then even more strange was that parent and child started taking turns with printfs, outputting only one line each until parent finished the loop since it had a headstart then child got to print the rest of i values. Again how is this behavior explained?

Here's the output i got:

parent, pid = 3246, i = 0
parent, pid = 3246, i = -1
parent, pid = 3246, i = -2
parent, pid = 3246, i = -3
parent, pid = 3246, i = -4
parent, pid = 3246, i = -5
parent, pid = 3246, i = -6
parent, pid = 3246, i = -7
parent, pid = 3246, i = -8
parent, pid = 3246, i = -9
parent, pid = 3246, i = -10
parent, pid = 3246, i = -11
parent, pid = 3246, i = -12
parent, pid = 3246, i = -13
parent, pid = 3246, i = -14
parent, pid = 3246, i = -15
parent, pid = 3246, i = -16
parent, pid = 3246, i = -17
parent, pid = 3246, i = -18
parent, pid = 3246, i = -19
parent, pid = 3246, i = -20
parent, pid = 3246, i = -21
parent, pid = 3246, i = -22
parent, pid = 3246, i = -23
parent, pid = 3246, i = -24
parent, pid = 3246, i = -25
parent, pid = 3246, i = -26
parent, pid = 3246, i = -27
parent, pid = 3246, i = -28
parent, pid = 3246, i = -29
parent, pid = 3246, i = -30
parent, pid = 3246, i = -31
parent, pid = 3246, i = -32
parent, pid = 3246, i = -33
parent, pid = 3246, i = -34
parent, pid = 3246, i = -35
parent, pid = 3246, i = -36
parent, pid = 3246, i = -37
parent, pid = 3246, i = -38
parent, pid = 3246, i = -39
parent, pid = 3246, i = -40
parent, pid = 3246, i = -41
parent, pid = 3246, i = -42
parent, pid = 3246, i = -43
parent, pid = 3246, i = -44
parent, pid = 3246, i = -45
parent, pid = 3246, i = -46
parent, pid = 3246, i = -47
parent, pid = 3246, i = -48
parent, pid = 3246, i = -49
parent, pid = 3246, i = -50
child, pid = 3247, i = 0
parent, pid = 3246, i = -51
parent, pid = 3246, i = -52
child, pid = 3247, i = 1
parent, pid = 3246, i = -53
child, pid = 3247, i = 2
parent, pid = 3246, i = -54
child, pid = 3247, i = 3
parent, pid = 3246, i = -55
child, pid = 3247, i = 4
parent, pid = 3246, i = -56
child, pid = 3247, i = 5
parent, pid = 3246, i = -57
child, pid = 3247, i = 6
parent, pid = 3246, i = -58
child, pid = 3247, i = 7
parent, pid = 3246, i = -59
child, pid = 3247, i = 8
parent, pid = 3246, i = -60
child, pid = 3247, i = 9
parent, pid = 3246, i = -61
child, pid = 3247, i = 10
parent, pid = 3246, i = -62
child, pid = 3247, i = 11
parent, pid = 3246, i = -63
child, pid = 3247, i = 12
parent, pid = 3246, i = -64
child, pid = 3247, i = 13
parent, pid = 3246, i = -65
child, pid = 3247, i = 14
parent, pid = 3246, i = -66
child, pid = 3247, i = 15
parent, pid = 3246, i = -67
child, pid = 3247, i = 16
parent, pid = 3246, i = -68
child, pid = 3247, i = 17
parent, pid = 3246, i = -69
child, pid = 3247, i = 18
parent, pid = 3246, i = -70
child, pid = 3247, i = 19
parent, pid = 3246, i = -71
child, pid = 3247, i = 20
parent, pid = 3246, i = -72
child, pid = 3247, i = 21
parent, pid = 3246, i = -73
child, pid = 3247, i = 22
parent, pid = 3246, i = -74
child, pid = 3247, i = 23
parent, pid = 3246, i = -75
child, pid = 3247, i = 24
parent, pid = 3246, i = -76
child, pid = 3247, i = 25
parent, pid = 3246, i = -77
child, pid = 3247, i = 26
parent, pid = 3246, i = -78
child, pid = 3247, i = 27
parent, pid = 3246, i = -79
child, pid = 3247, i = 28
parent, pid = 3246, i = -80
child, pid = 3247, i = 29
parent, pid = 3246, i = -81
child, pid = 3247, i = 30
parent, pid = 3246, i = -82
child, pid = 3247, i = 31
parent, pid = 3246, i = -83
child, pid = 3247, i = 32
parent, pid = 3246, i = -84
child, pid = 3247, i = 33
parent, pid = 3246, i = -85
child, pid = 3247, i = 34
parent, pid = 3246, i = -86
child, pid = 3247, i = 35
parent, pid = 3246, i = -87
child, pid = 3247, i = 36
parent, pid = 3246, i = -88
child, pid = 3247, i = 37
parent, pid = 3246, i = -89
child, pid = 3247, i = 38
parent, pid = 3246, i = -90
child, pid = 3247, i = 39
parent, pid = 3246, i = -91
child, pid = 3247, i = 40
parent, pid = 3246, i = -92
child, pid = 3247, i = 41
parent, pid = 3246, i = -93
child, pid = 3247, i = 42
parent, pid = 3246, i = -94
child, pid = 3247, i = 43
parent, pid = 3246, i = -95
child, pid = 3247, i = 44
parent, pid = 3246, i = -96
child, pid = 3247, i = 45
parent, pid = 3246, i = -97
child, pid = 3247, i = 46
parent, pid = 3246, i = -98
child, pid = 3247, i = 47
parent, pid = 3246, i = -99
child, pid = 3247, i = 48
child, pid = 3247, i = 49
child, pid = 3247, i = 50
child, pid = 3247, i = 51
child, pid = 3247, i = 52
child, pid = 3247, i = 53
child, pid = 3247, i = 54
child, pid = 3247, i = 55
child, pid = 3247, i = 56
child, pid = 3247, i = 57
child, pid = 3247, i = 58
child, pid = 3247, i = 59
child, pid = 3247, i = 60
child, pid = 3247, i = 61
child, pid = 3247, i = 62
child, pid = 3247, i = 63
child, pid = 3247, i = 64
child, pid = 3247, i = 65
child, pid = 3247, i = 66
child, pid = 3247, i = 67
child, pid = 3247, i = 68
child, pid = 3247, i = 69
child, pid = 3247, i = 70
child, pid = 3247, i = 71
child, pid = 3247, i = 72
child, pid = 3247, i = 73
child, pid = 3247, i = 74
child, pid = 3247, i = 75
child, pid = 3247, i = 76
child, pid = 3247, i = 77
child, pid = 3247, i = 78
child, pid = 3247, i = 79
child, pid = 3247, i = 80
child, pid = 3247, i = 81
child, pid = 3247, i = 82
child, pid = 3247, i = 83
child, pid = 3247, i = 84
child, pid = 3247, i = 85
child, pid = 3247, i = 86
child, pid = 3247, i = 87
child, pid = 3247, i = 88
child, pid = 3247, i = 89
child, pid = 3247, i = 90
child, pid = 3247, i = 91
child, pid = 3247, i = 92
child, pid = 3247, i = 93
child, pid = 3247, i = 94
child, pid = 3247, i = 95
child, pid = 3247, i = 96
child, pid = 3247, i = 97
child, pid = 3247, i = 98
child, pid = 3247, i = 99
power_output
  • 411
  • 10
  • 26

2 Answers2

0

The parent process starts first.

The point here is that you are running multiple processes, which run "in parallel". Now, in the real life they may or may not run in parallel. In old processors having only one core, the parallel execution means that the operating system is quickly cycling around the runnable processes, and runs a bit from each of them. Such "bit" is called time slice, and it is usually around 10ms.

Nowadays with the age of multicore cpus, you may see things really running in parallel.

So you can see:

  • first only the parent runs for one time slice
  • then both parent and child runs for one time slice
  • and finally only the clild runs.

The actual scheduling between processes (using one core or more, when to switch amongst processes) depends on the operating system you're using.

Gee Bee
  • 1,794
  • 15
  • 17
  • The 'time slice' is irrelevant. It's just waffle in this case, (and indeed, most cases:). – Martin James Mar 14 '16 at 14:36
  • It is not relevant in this case, agreed. I still think it helps a bit to understand why parent process *only* runs alone first. I found time slices can be a show stopper for other use cases (real-time programming, user-mode drivers, and a lot more.) Our cases differ ;-) – Gee Bee Mar 14 '16 at 14:46
0

You should note that your processes execute hundreds of thousands of instruction codes, most of them, by far, inside the lock that protects the stdout stream from access by multiple threads. The code you actually type in, and show in your question, is next-to-nothing.

The behaviour of the processes is 99.9999% competely managed by the lock on stdout, hence 'that parent and child started taking turns' - totally expected as they loop around the lock.

Martin James
  • 24,453
  • 3
  • 36
  • 60