Forking


fork() is implemented via clone(), which in turn called do_fork() that does the bulk of the work

do_fork() then calls copy_process(), which does the following

  1. Call dup_task_struct()
    • This creates a new kernel stack, thread_info and task_struct structure for the duplicated process. The child and parent still have identical PID
  2. Check if the new child does not exceed number of allowed processes
  3. Various values of the process descriptor are cleared or set to initial values
  4. Child is set to TASK_UNINTERRUPTIBLE, meaning it cannot run yet
  5. Call copy_flags()
    • This updates the flags in the new task_struct. PF_SUPERPRIV indicates if the task used super-user is cleared. PF_FORKNOEXEC indicates a process has not yet called exec() is set
  6. Call alloc_pid()
    • This assigns an available PID to the new process
  7. Depending on the flags passed to clone(), either duplicate or shares open files, filesystem information, signal handlers, process address space and name space
  8. Clean up and return pointer of the new process to caller do_fork()

If copy_process() returns successfully, the child is woken up and run.

The kernel runs the newly created child first. This is so copy-on-write can happen (If the parent ran first and wrote to the data, all the data will be copied to the child, inducing overhead if the child calls exec())

results matching ""

    No results matching ""