I am trying to understand how forks work in C, but I am misunderstanding something somewhere.
I came across a test one of my professor gave me last year, but I couldn't reply to it: We have 3 tasks (process or threads), with the following pseudo-code:
Th1 { display "Hello 1" }
Th2 { display "Hello 2" }
Th3 { display "Hello 3" }
main() {
Fork(Th1);Fork(Th2);Fork(Th3);
}
The question was: Which is the order of the execution of these tasks? Why?
How can I reply to this? Is there any guide or any useful ressource where I can understand how forks, semaphores and memory allocation ?
I am a real newbie on at low level programming.
The details you are asking about are intentionally unspecified. The way you should imagine it happening is that after each "fork" operation, the parent and child processes are running simultaneously and there is no ordering between things they do unless you explicitly make there be an ordering.
The pseudocode program you showed could print "Hello 1", "Hello 2", and "Hello 3" in any order, and it could be a different order each time you ran it, depending on accidents of what happens to be going on elsewhere in the system.
Contrast this pseudocode program:
This one is guaranteed to print "Hello main", "Hello 1", "Hello 2", "Hello 3" in that order. Do you see why?
Unfortunately, there's no reference I can point you at that is clear, concise, and online. There is this sentence in the specification of
fork
:but you have to know how to read standardese to know that this implies everything I said above. Everything else I can think of is textbook-length, e.g. W. Richard Stevens' Advanced Programming in the Unix Environment which you might want to see if your library has a copy of.
Fork is not part of C. In some operating systems (notably eunuchs variants) that directly support the fork concept,it is a system service. In other operating systems, fork is a library call that mimics the "fork concept."
That is undefined. The order of creation will be 1, 2, 3 but the order they execute cannot be predicted, especially in a multi-processor system.
In the forking model, each fork creates a duplicate of the parent process. The child typically then loads a new executable and runs it. In your simple pseudocode, you could do what you want without running a new executable but anything more significant than just printing out messages is likely to require each sub process to have a separate executable that runs.
Your ordering problem is undermined by the fact that execution of a program does not occur in a straight line. Even in a single processor system, 1, 2, 3 are not likely to run start-to-finish without interruption, Each time you do "display" your process is likely to yield the CPU to another process. You process can also have page faults that will yield as well. If you do load another executable, that will add to the variability.
The sequence problem is even greater in a multi-processor system. Suppose you have four processors and each child process is allocated to a separate process's work queue. The order of execution depends upon what happens at the front of each processor's work queue.
If you do this on a system that mimic's eunuch's fork model, there will be even greater variability, because the process copy semantics will be different.