CSE 2431
Unix/Linux fork()
1. To create a process, Unix/Linux use fork(), which is a system call.
2. When fork() is executed by a process:
a. The process executing fork(), called the parent, makes a system call to the OS which causes a new process (a child of the parent) to be created (assuming no error occurs, and they occur very rarely).
b. The fork() system call returns (in the return register, as always):
If an error occurs, -1 is returned to the parent, and no child process is created; else
i. The pid of the child is returned to the parent;
ii. 0 is returned to the child.
c. Notice that the different return values for the parent and child can be used to have the parent and child execute different code after return from the fork system call.
d. When the OS creates the child, the child is assigned its own pid by the OS, and its pid will be greater than the pid of its parent (often 1 greater, but it depends on whether or not any other fork system calls were made (by other processes running in the system) between the time the parent was created and the time the fork call is made in the parent).
e. The child gets its own separate address space (its own space in memory), which initially contains a copy of the parent¡¯s address space (both code and data).
f. Linux implements fork() using copy-on-write pages [discussed later], so process creation is quite efficient.
g. As part of creating the child process, the OS will also create a process control block (PCB) for the child, which will be used by the OS to keep track of data needed to manage the process, such as the pid of the process, current process execution state (register values), process state (ready, running, blocked), open files, etc.
h. Notice carefully that the child ALSO gets a copy of the parent¡¯s register values (PC, PSR, in Intel, rax, rbx, etc.), except the parent¡¯s rax will be overwritten by the fork return value to the child (0).
i. In some cases, the child process may subsequently overwrite its address space with a different program to execute. This can be done using exec() system calls, such as execvp() [discussed later].
j. Notice carefully: When the parent process resumes execution, the PC had already been incremented to the address of the next instruction after the fork() instruction when the fork instruction executed, so the fork() call is only made once by the parent (that is, the parent will start executing instructions starting with the next instruction after the fork when the parent runs again). Also notice carefully that the child gets a copy of all the code and data for the parent, and also all of the parent¡¯s registers (context), so the child also gets the incremented PC (which has the address of the next instruction after the fork() call); therefore, the child will not execute the fork call, but rather, will start executing instructions starting with the first instruction after the fork instruction.