Skip to main content
  1. Notes/
  2. Linux Kernel/

Process Creation

Unix approach to Process Creation
#

Unline most operating systems, where a spawn mechanism is used to create a process in a new address space, read the executable file into that space, and start executing it, Unix uses a two-step approach:

  1. fork(): Creates a child process that is a duplicate of the parent process, with a different process ID. Its PPID (parent process ID) is set to the PID of the parent. And certain resources and statistics, such as pending signals, are not inherited by the child process.
  2. exec(): Loads the new executable into the address space and begins its execution. The combination of these two are the same as spawning a new process in other operating systems. exec() is a family of functions. The kernel implements the execve() system call, on top of which various library functions are built like execlp(), execle(), execv(), and execvp().

This is the same approach used in Linux.

Forking in Linux
#

Traditionally
#

Upon fork(), all resources owned by parents are duplicated and copy given to the child, which is a very inefficient and naive approach. Because:

  • It copies data which otherwise could be shared.
  • If the execution was immidiate all that copying is wasted.

Copy-On-Write(COW)
#

In Linux, fork() is implemented usign copy-on-write pages.

What is a page?

A page is the smallest unit of memory management in virtual memory. Linux can support:

  • Huge pages (2MB)
  • Gigantic pages (1GB)
  • Standard pages (4KB)

Copy-on-Write means that the pages are not copied immediately. Instead, both the parent and child processes share the same physical pages marked as read-only. When either process attempts to write to a shared page, a page fault occurs. The kernel then allocates a new physical page, copies the contents of the original page to the new page, and updates the page table(mostly pointers) of the writing process to point to the new page, which is now writable.

Because of this:

  • Most of the time, nothing is copied at fork().
  • If the child immediately calls exec() (very common), no pages are ever copied at all.

So the real work done by fork() is very small:

  • Create a new process descriptor (task_struct).
  • Copy the page tables (the structures that point to memory), not the actual memory.

References
#