tyy
tyy

Reputation: 51

Where does the process start to execute after fork()

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>


int main(void) {
    for (int i = 1; i < 4; i++) {
        printf("%d", i);
        int id = fork();
        if (id == 0) {
            printf("Hello\n");
            exit(0);
        } else {
            exit(0);
        }
    }
    return 0;
}

For this code, it prints 11Hello on my computer. It seems counter-intuitive to me because "1" is printed twice but it's before the fork() is called.

Upvotes: 5

Views: 914

Answers (3)

To begin with, the for loop is superfluous in your example.

Recall that the child copies the caller's memory(that of its parent) (code, globals, heap and stack), registers, and open files. To be performant or there may be some other reason, the printf call may not flush the buffer and put the things passed to that except for some cases such as appending new-line-terminator.

Before forking, the parent(main process) is on the way.

Let's assume we're on a single core system and the child first preempts the core.

1 is in the buffer because its parent put it into that before forking. Then, the child reaches second print statement, a caveat here is that the child can be orphaned at that time(no matter for this moment), passing "Hello\n" string including new-line character giving rise to dump the buffer/cache(whatever you call.) Since it sees \n character, it flushes the buffer including prior 1 added by its parent, that is 11Hello.

Let's assume the parent preempts the core at first,

It surrenders after calling exit statement, bringing on the child to be orphaned, causing memory leak. After that point, the boss(init possessing process id as 1) whose newly name I forget(it may be sys-something) should handle this case. However, nothing is changed as to the printing-steps. So you run into again 11Hello except if not the buffer is flushed automagically.

I don't have much working experience with them but university class(I failed at the course 4 times). However, I can advise you whenever possible use stderr while coping with these tings since it is not buffered, in lieu of stdout or there is some magical way(I forget it again, you call it at the beginning in main()) you can opt for to disable buffering for stdout as well.

To be more competent over these topics, you should glance at The Linux Programming Interface of Michael Kerrisk and the topics related to William Pursell, Jonathan Leffler, WhozCraig, John Bollinger, and Nominal Animal. I have learnt a plethora of information from them even if the information almost wholly is useless in Turkey borders.

*Magic means needing a lot of details to explain.

Upvotes: 0

Tony Tannous
Tony Tannous

Reputation: 14866

Where does the process start to execute after fork()

fork() duplicates the image of the process and it's context. It will run the next line of code pointed by the instruction pointer.


It seems counter-intuitive to me because "1" is printed twice but it's before the fork() is called.

Read printf anomaly after "fork()"

Upvotes: 0

Vens8
Vens8

Reputation: 85

The fork() system call forks a new process and executes the instruction that follows it in each process parallelly. After your child process prints the value of i to the stdout, it gets buffered which then prints the value of 'i' again because stdout was not flushed.

Use the fflush(stdout); so that 'i' gets printed only once per fork.

Alternately, you could also use printf("%d\n", i); where the new line character at the end does the job.

Upvotes: 1

Related Questions