EmbLogic's Blog

FORK() call–kernal point of view

when the fork system call is invoked the fork is mappped with the clone system call .
the kernel stores the list of processes in circular doubly link list called task list
each element in the task_list is a process descriptor of type struct task_struct which is defined in
->task_struct contain all the information related to the process

->the process descriptor contain the data that described the execution program-openfile,the process address space ,pending signals ,p
->the task_struct contain the parent pid task_struct.

struct task_struct
{
process descriptor
unsigned long state;
int prio;
unsigned long policy;
struct task_struct *parent; //struct task_struct of the parent
struct list_head tasks;
pid_t pid;
} process_descriptor;
the linklist produced by this task_struct consicute the Kernel process table whos first process after booting process is the init pro
kthreadadd function to make more system related processes needed for the operation of the system OS.

struct task_struct was stored at the end of the kernel stack of each process

Linux implements fork() via the clone() system call.This call takes a series of flags that
specify which resources, if any, the parent and child process should share.The
fork(), vfork(), and __clone() library calls all invoke the clone() system call with the
requisite flags.The clone() system call, in turn, calls do_fork().

The bulk of the work in forking is handled by do_fork(), which is defined in
kernel/fork.c.This function calls copy_process() and then starts the process running.
The interesting work is done by copy_process():

1. It calls dup_task_struct(), which creates a new kernel stack, thread_info struc-
ture, and task_struct for the new process.The new values are identical to those of
the current task.At this point, the child and parent process descriptors are identical.

2. It then checks that the new child will not exceed the resource limits on the num-
ber of processes for the current user.

3. The child needs to differentiate itself from its parent.Various members of the
process descriptor are cleared or set to initial values. Members of the process
descriptor not inherited are primarily statistically information.The bulk of the val-
ues in task_struct remain unchanged.

4. The child’s state is set to TASK_UNINTERRUPTIBLE to ensure that it does not yet run.

5.copy_process() calls copy_flags() to update the flags member of the
task_struct.

6. It calls alloc_pid() to assign an available PID to the new task.

7. Depending on the flags passed to clone(), copy_process() either duplicates or
shares open files, filesystem information, signal handlers, process address space, and
namespace.These resources are typically shared between threads in a given process;
otherwise they are unique and thus copied here.

8. Finally, copy_process() cleans up and returns to the caller a pointer to the new
child.
Back in do_fork(), if copy_process() returns successfully, the new child is woken up
and run. Deliberately, the kernel runs the child process first. In the common case of the
child simply calling exec() immediately, this eliminates any copy-on-write overhead that
would occur if the parent ran first and began writing to the address space.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>